LeetCode 1143. 最长公共子序列 | 动态规划详解

1143. 最长公共子序列

题目描述

给定两个字符串 text1text2,返回它们的 最长公共子序列(LCS) 的长度。
如果不存在公共子序列,则返回 0。

示例:

输入: text1 = "abcde", text2 = "ace"
输出: 3
解释: 最长公共子序列是 "ace"

解题思路:动态规划(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] = max(dp[i-1][j], dp[i][j-1])

✅ 初始化

  • dp[0][j] = 0dp[i][0] = 0 表示空串参与比较时 LCS 长度为 0。

✅ Python代码实现(动态规划) 

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m, n = len(text1), len(text2)
        dp = [[0] * (n + 1) for _ in range(m + 1)]

        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if text1[i - 1] == text2[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]

时间 & 空间复杂度分析 

项目 复杂度
时间复杂度 O(m * n)
空间复杂度 O(m * n)

✅ 可进一步优化为 O(min(m,n)) 空间复杂度,使用滚动数组实现。 

延伸思考

  • 如果需要返回 最长公共子序列本身,可以通过记录路径倒推构造。

  • LCS 常用于 版本比较DNA比对文本相似度 等场景。

  • 与此题相关的变体:

    • 编辑距离(Leetcode 72)

    • 最长重复子数组(Leetcode 718)

 

你可能感兴趣的:(leetcode,动态规划,算法)