最长公共子串
子串的要求比子序列严格,所以可以讨论子串的终点
def longestCommonSubsequence_(self, s, p):
if not s or not p:
return 0
res = 0
dp = [[0]*(len(p)+1) for _ in range(len(s)+1)]
for i in range(1, len(s)+1): # 一定要注意坐标的定义
for j in range(1, len(p)+1): # 这里的i,j定义的是dp数组的坐标 比字符串的坐标大1
if s[i-1] == p[j-1]:
dp[i][j] = 1 + dp[i-1][j-1]
res = max(res, dp[i][j])
return res
最长公共子序列
DP解
def longestCommonSubsequence(self, s, p):
if not s or not p:
return 0
dp = [[0]*(len(p)+1) for _ in range(len(s)+1)]
for i in range(1, len(s)+1): # 一定要注意坐标的定义
for j in range(1, len(p)+1): # 这里的i,j定义的是dp数组的坐标 比字符串的坐标大1
if s[i-1] == p[j-1]:
dp[i][j] = 1 + dp[i-1][j-1]
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
return dp[-1][-1]
递归+memo
def LongCommonSubSequence_rec(self, s, p):
memo = {} # 定义memo[(i,j)] 是s[:i] p[:j] 右边是开区间 的最长子序列
def dp(i, j): # i,j是memo的坐标
if (i, j) in memo:
return memo[(i, j)]
if i == 0 or j == 0: # 某一个字符串已经扫描完
res = 0
elif s[i - 1] == p[j - 1]: # 字符串坐标比memo坐标小1
res = 1 + dp(i - 1, j - 1)
else:
res = max(dp(i - 1, j), dp(i, j - 1))
memo[(i, j)] = res
return res
return dp(len(s), len(p))
最长公共回文串
对称轴拓展法
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
self.res = ""
def expandAroundCenter(left, right):
l, r = left, right
while l >= 0 and r < len(s) and s[l] == s[r]:
l -= 1
r += 1
if r - l - 1 > len(self.res):
self.res = s[l + 1:r]
for i in range(0, len(s)):
expandAroundCenter(i, i)
expandAroundCenter(i, i + 1)
return self.res
DP解
def longestPalindrome(self, s):
n = len(s)
maxStr = ''
DP = [[0] * n for _ in range(n)] # 这么创建二维list 存放 的是实值不是引用
for j in range(n): # 终点
for i in range(0, j + 1): # 起点
if (j - i < 2 or DP[i + 1][j - 1]) and s[i] == s[j]: #包含两种情况 i,i i,i+1
DP[i][j] = 1
if DP[i][j] and j - i + 1 > len(maxStr):
maxStr = s[i:j + 1]
return maxStr
最长公共回文子序列
DP
def subSeq(self, s):
dp = [[0] * len(s) for _ in range(len(s))] # dp(i,j)定位为s[i,j]的最长回文子序列
for i in range(len(s) - 1, -1, -1): # 起点
dp[i][i] = 1
for j in range(i + 1, len(s)): # 终点
if s[i] == s[j]:
dp[i][j] = dp[i + 1][j - 1] + 2
else:
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
return dp[0][-1]
递归+memo
def subSeq_rec(self, s):
memo = {}
def dp(i, j): # 定义dp(i,j)为子串i到j中最大子序列
if (i, j) in memo:
return memo[(i, j)]
if i == j:
return 1
elif s[i] == s[j]:
if j - i == 1:
return 2
else:
res = dp(i + 1, j - 1) + 2
else:
res = max(dp(i + 1, j), dp(i, j - 1))
memo[(i, j)] = res
return memo[(i, j)]
return dp(0, len(s) - 1)
网友评论