📅  最后修改于: 2023-12-03 15:40:16.970000             🧑  作者: Mango
最长公共子序列(Longest Common Subsequence,简称 LCS)是指两个序列中的最长公共子序列。
LCS 问题是一个经典的计算机科学问题,常常被用于比较两个字符串的相似度。
最长公共子序列问题可以使用动态规划求解。我们可以使用一个二维数组 $dp$,其中 $dp[i][j]$ 表示 $text1$ 的前 $i$ 个元素和 $text2$ 的前 $j$ 个元素的最长公共子序列的长度。
状态转移方程:
如果 $text1[i-1] == text2[j-1]$,则 $dp[i][j] = dp[i - 1][j - 1] + 1$; 否则,$dp[i][j]$ 的值为 $dp[i - 1][j]$ 和 $dp[i][j - 1]$ 中的最大值。
通过计算 $dp$ 数组中的每一个元素,最终 $dp[m][n]$ 即为 $text1$ 和 $text2$ 的最长公共子序列的长度。
可以通过进行迭代的方式逐步填充 $dp$ 数组。为了避免重复计算,我们可以使用一个字典 $memo$,其中 $memo[i][j]$ 表示计算过的 $dp[i][j]$ 的值,如果之前计算过,则直接从字典中取值,否则进行计算。
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
m, n = len(text1), len(text2)
memo = [[-1] * (n + 1) for _ in range(m + 1)]
return self.dfs(text1, text2, m, n, memo)
def dfs(self, text1, text2, i, j, memo):
if memo[i][j] != -1:
return memo[i][j]
if i == 0 or j == 0:
return 0
if text1[i - 1] == text2[j - 1]:
memo[i][j] = self.dfs(text1, text2, i - 1, j - 1, memo) + 1
else:
memo[i][j] = max(self.dfs(text1, text2, i - 1, j, memo), self.dfs(text1, text2, i, j - 1, memo))
return memo[i][j]
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int m = text1.length(), n = text2.length();
int[][] memo = new int[m + 1][n + 1];
for (int[] row : memo) {
Arrays.fill(row, -1);
}
return dfs(text1, text2, m, n, memo);
}
private int dfs(String text1, String text2, int i, int j, int[][] memo) {
if (memo[i][j] != -1) {
return memo[i][j];
}
if (i == 0 || j == 0) {
return 0;
}
if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
memo[i][j] = dfs(text1, text2, i - 1, j - 1, memo) + 1;
} else {
memo[i][j] = Math.max(dfs(text1, text2, i - 1, j, memo), dfs(text1, text2, i, j - 1, memo));
}
return memo[i][j];
}
}