Longest Common Substring (Shortest Common Superstring)
https://leetcode.com/problems/shortest-common-supersequence/
这两个问题是相同的其实
以下是Bottom-up DP的做法
class Solution:
def shortestCommonSupersequence(self, str1: str, str2: str) -> str:
def lcs(str1,str2):
m = len(str1)
n = len(str2)
dp= [[""]*(1+n) for _ in range(m+1)]
for i in range(1,m+1):
for j in range(1,n+1):
if str1[i-1] == str2[j-1]:
dp[i][j] = dp[i-1][j-1] + str1[i-1]
else:
dp[i][j] = max(dp[i-1][j],dp[i][j-1],key=len)
return dp[-1][-1]
res =""
i = 0
j = 0
#print(lcs(str1,str2))
for c in lcs(str1,str2):
while str1[i] != c:
res+=str1[i]
i+=1
while str2[j] != c:
res+= str2[j]
j+=1
res += c
i+=1
j+=1
return res + str1[i:] + str2[j:]
当然用recursion也是可以做的,需要用一个cache来存之前recursion计算过的值这样可以把recursion的O(2^N)的降为O(MN)
m = len(text1)
n = len(text2)
self.dp=[n*[0] for _ in range(m)]
def lcm(s1,s2,i,j):
if i >= len(s1) or j >= len(s2):
return 0
if self.dp[i][j] != 0:
return self.dp[i][j]
if s1[i] == s2[j]:
self.dp[i][j] = lcm(s1,s2,i+1,j+1)+1
return self.dp[i][j]
self.dp[i][j]= max(lcm(s1,s2,i,j+1),lcm(s1,s2,i+1,j))
return self.dp[i][j]
return lcm(text1,text2,0,0)
这个recursion若用DP做法如下
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
m = len(text1)
n = len(text2)
dp=[(1+n)*[0] for _ in range(m+1)]
res=0
for i in range(1,m+1):
for j in range(1,n+1):
if text1[i-1] == text2[j-1]:
dp[i][j] = dp[i-1][j-1]+1
else:
dp[i][j] = max(dp[i-1][j],dp[i][j-1])
res = max(res,dp[i][j])
return res
Last updated
Was this helpful?