求两个字符串的公共最长序列。
例如,
- 输入:‘acbde’ , ‘cfebd’
- 输出:3 (最长的公共子序列为’cbd’)
动态规划:
- i == 0 or j == 0, dp[i][j] = 0
- A[i] == B[j], dp[i][j] = dp[i−1][j−1]+1
- A[i] != B[j], dp[i][j] = max(dp[i−1][j], dp[i][j−1])
class Solution:
def findLength(self, A: List[int], B: List[int]) -> int:
m = len(A)
n = len(B)
dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
for i in range(n + 1):
for j in range(m + 1):
if i == 0 or j == 0:
dp[i][j] = 0
elif B[i - 1] == A[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return dp[-1][-1]
特别强调:
注意区分这两个概念:
- 最长公共子序列
- 最长公共子串
最长公共子串要求的是连续,而最长公共子序列不一定连续;
所以例子中的两个字符串’acbde’,‘cfebd’:
- 输出 3 ‘cbd’
- 输出 2 ‘bd’
动态规划的条件差不多:
- i == 0 or j == 0, dp[i][j] = 0
- A[i] == B[j], dp[i][j] = dp[i−1][j−1]+1
- 最后输出要输出最大值
class Solution:
def findLength(self, A: List[int], B: List[int]) -> int:
m = len(A)
n = len(B)
dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
for i in range(n + 1):
for j in range(m + 1):
if i == 0 or j == 0:
dp[i][j] = 0
elif B[i - 1] == A[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
return max(max(row) for row in dp)