最长公共子序列问题(Longest Common Subsequence,LCS)

title

最长公共子序列问题(Longest Common Subsequence,LCS)是计算两个字符串之间最长公共子序列的问题。公共子序列指的是两个或多个序列中都存在的子序列,而最长公共子序列是指最长的公共子序列。最长公共子序列问题被广泛地应用在文本比较、DNA 序列分析等领域。

假设有两个字符串 s1 和 s2,我们的任务是找出它们之间的最长公共子序列。假设 s1 的长度为 m,s2 的长度为 n,我们可以使用动态规划的思想来解决这个问题。具体步骤如下:

定义状态:设 dp[i][j] 表示字符串 s1 的前 i 个字符和字符串 s2 的前 j 个字符之间的最长公共子序列的长度。

初始化状态:dp[0][j] = 0 和 dp[i][0] = 0,表示一个字符串的前 0 个字符和另一个字符串的前 j 个字符之间的最长公共子序列长度为 0。

状态转移方程:当 s1[i-1] == s2[j-1] 时,dp[i][j] = dp[i-1][j-1] + 1;否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1])。

返回结果:dp[m][n] 即为字符串 s1 和 s2 之间的最长公共子序列的长度。

以下是Java代码实现最长公共子序列问题:

public static int longestCommonSubsequence(String s1, String s2) {
    int m = s1.length(), n = s2.length();
    int[][] dp = new int[m+1][n+1];
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s1.charAt(i-1) == s2.charAt(j-1)) {
                dp[i][j] = dp[i-1][j-1] + 1;
            } else {
                dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
            }
        }
    }
    return dp[m][n];
}

在上述代码中,我们使用了一个二维数组 dp 来记录状态。注意,为了方便代码实现,我们使用了从 1 开始的下标,因此在比较字符时需要使用 s1.charAt(i-1) 和 s2.charAt(j-1)。最后,我们返回 dp[m][n],即字符串 s1 和 s2 之间的最长公共子序列的长度。

例如,对于字符串 s1 = "abcde" 和 s2 = "ace",它们之间的最长公共子序列为 "ace",其长度为 3。运行 longestCommonSubsequence(s1, s2),将返回 3。

powered by Gitbook© 2023 编外计划 | 最后修改: 2023-11-24 03:37:00

results matching ""

    No results matching ""