deflongestCommonSubsequence(str1, str2) -> int: defdp(i, j): # 空串的 base case if i == -1or j == -1: return0 if str1[i] == str2[j]: # 这边找到一个 lcs 的元素,继续往前找 return dp(i - 1, j - 1) + 1 else: # 谁能让 lcs 最长,就听谁的 return max(dp(i-1, j), dp(i, j-1)) # i 和 j 初始化为最后一个索引 return dp(len(str1)-1, len(str2)-1)
2. 法二,借用DP Table来记录(也可用备忘录)
双层遍历:
判断:当前两个字符一样吗?
一样:左斜上角空格数字(dp[i-1][i-1]) 加1;
不一样:比较 上 && 下 的最大值,取大的那一个来填充当前dp[ i ][ j ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
deflongestCommonSubsequence(str1, str2) -> int: m, n = len(str1), len(str2) # 构建 DP table 和 base case dp = [[0] * (n + 1) 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]: # 找到一个 lcs 中的字符 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]
3. 优化:用动态数组(一维数组)来解决:
在利用二维dp数组记录dp[ i ][ j ]时,需要用到dp[ i-1 ][ j-1 ] (左上方),dp[ i-1 ][ j ] (上边),dp[ i ][ j-1 ] (左边)。