📜  门| GATE-CS-2006 |第 72 题(1)

📅  最后修改于: 2023-12-03 15:42:16.229000             🧑  作者: Mango

题目描述

本题为 Gate-CS-2006 的第 72 题,要求编写一个程序,实现给定两个字符串的最长公共子序列的求解。

解题思路

动态规划是应对字符串最长公共子序列问题的一种有效方法。定义一个二维矩阵 dp,其中 dp[i][j] 表示第一个字符串的前 i 个字符和第二个字符串的前 j 个字符的最长公共子序列长度。则dp[i][j]的求解方法如下:

  • 当第一个字符串第 i 个字符和第二个字符串第 j 个字符相同时,可以将它们添加到最长公共子序列中,同时该最长公共子序列长度为 dp[i-1][j-1] + 1,因为只有这样才能让最长公共子序列长度加 1。
  • 当第一个字符串第 i 个字符和第二个字符串第 j 个字符不同时,则最长公共子序列长度为 dp[i-1][j] 和 dp[i][j-1] 中的最大值,因为该字符可能只存在于一个字符串中,另一个字符串中没有。

最终,dp[m][n] 即为最长公共子序列长度,其中 m 为第一个字符串长度,n 为第二个字符串长度。

最长公共子序列的求解可以借助 dp 的矩阵,从右下角开始,通过回溯 dp 矩阵,确定最长公共子序列中的字符。

代码实现

以下是 Python 代码实现:

def longest_common_subsequence(str1, str2):
    m, n = len(str1), len(str2)
    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]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    lcs = ''
    i, j = m, n
    while i > 0 and j > 0:
        if str1[i-1] == str2[j-1]:
            lcs = str1[i-1] + lcs
            i, j = i-1, j-1
        elif dp[i-1][j] > dp[i][j-1]:
            i -= 1
        else:
            j -= 1
    return dp[m][n], lcs

其中,str1str2 分别代表输入的两个字符串。函数返回的第一个元素为最长公共子序列长度,第二个元素为最长公共子序列字符串。

总结

本题涉及到动态规划的应用,需要在理解 dp 的基础上,结合实际情况找到具体的求解策略。最长公共子序列求解是一种典型的问题,需要掌握其基本算法思想。