📜  最长公共子序列 | DP-4(1)

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

最长公共子序列 | DP-4

最长公共子序列(Longest Common Subsequence,LCS)问题是计算两个序列之间最长的子序列的长度,该子序列在两个原序列中都出现,不一定连续。

该问题可以通过动态规划(DP)求解,使用一个二维的表格来记录长度和对应的公共子序列。下面是该问题的算法和示例代码。

算法步骤
  1. 创建一个二维的表格,行数为s1的长度加1,列数为s2的长度加1,初始值全为0;
  2. 从第1行1列开始,逐行逐列填充表格:
    1. 如果s1[i-1]等于s2[j-1],则LCS[i][j]=LCS[i-1][j-1]+1,即左上角值加1;
    2. 如果s1[i-1]不等于s2[j-1],则LCS[i][j]等于LCS[i-1][j]和LCS[i][j-1]中的较大值;
  3. 返回LCS[s1长度][s2长度]即为最长公共子序列的长度。
示例代码

下面是Python实现的示例代码:

def longest_common_subsequence(s1: str, s2: str) -> int:
    m, n = len(s1), len(s2)
    # 创建二维表格,初始值为0
    lcs = [[0] * (n+1) for _ in range(m+1)]
    for i in range(1, m+1):
        for j in range(1, n+1):
            if s1[i-1] == s2[j-1]:
                lcs[i][j] = lcs[i-1][j-1] + 1
            else:
                lcs[i][j] = max(lcs[i-1][j], lcs[i][j-1])
    return lcs[m][n]
时间复杂度与空间复杂度

该算法的时间复杂度为O(mn),其中m和n分别为s1和s2的长度。空间复杂度也为O(mn),因为需要创建一个二维的表格来存储每个子问题的解。一些优化可以减少空间复杂度,但是时间复杂度仍然相同。

总结

最长公共子序列问题是动态规划中的典型应用,该问题可以通过维护一个二维表格来记录每个子问题的解。该算法的时间复杂度为O(mn),空间复杂度也为O(mn)。