📜  资质 |门 CS 1998 |第 42 题(1)

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

资质 |门 CS 1998 |第 42 题

题目描述

给定两个字符串,找出它们中最长的公共子序列。公共子序列是指两个字符串中都出现的字符序列,不一定连续。

例如,字符串“ABCD”和“ACDFG”的最长公共子序列为“ACD”。

解题思路

本题可以使用动态规划算法解决。我们可以定义一个二维数组dp,其中dp[i][j]表示字符串1的前i个字符和字符串2的前j个字符的最长公共子序列的长度。

根据最后一个字符是否相同,可以将问题分为两个子问题:

  1. 字符串1的前(i-1)个字符和字符串2的前j个字符的最长公共子序列的长度(不考虑字符i)
  2. 字符串1的前i个字符和字符串2的前(j-1)个字符的最长公共子序列的长度(不考虑字符j)

递推公式如下:

if s1[i-1] == s2[j-1]:
    # 如果字符相同,则最长公共子序列的长度加一
    dp[i][j] = dp[i-1][j-1] + 1
else:
    # 如果字符不同,则最长公共子序列的长度为两种情况中的最大值
    dp[i][j] = max(dp[i-1][j], dp[i][j-1])

最终结果即为dp[m][n],其中m和n分别为字符串1和字符串2的长度。

代码片段

下面是Python实现的代码片段:

def longest_common_subsequence(s1, s2):
    m, n = len(s1), len(s2)
    dp = [[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]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])

    return dp[m][n]
总结

本题是动态规划的经典应用之一,也是算法面试中较为常见的问题。对于初学者来说,可以通过多做类似的练习题来熟悉动态规划的基本思想,提高算法设计和实现的能力。