You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于最长公共子序列思路的最长公共子串解法可行性问询

关于最长公共子串(LCSubstring)DP解法的问题解答

嘿,我来帮你理清楚这个问题~首先得先把子序列和子串的核心区别掰明白:

  • 最长公共子序列(LCS):字符顺序一致,但不需要连续(比如"abc"和"aec"的LCS是"ac")
  • 最长公共子串(LCSubstring):必须是连续的一段字符(比如"abcde"和"abxde"的最长公共子串是"ab"或"de")

你的解法为什么不可行?

先看你写的最长公共子串递推逻辑:

if str1[i] != str2[j]: dp[i][j] = max(dp[i-1][j], dp[i][j-1])
else: 
    if str1[i-1] == str2[j-1]: dp[i][j] = 1 + dp[i-1][j-1]
    else: dp[i][j] = 1 + dp[i-1][j-1]

这里有两个致命问题:

  1. else里的判断完全没用——不管str1[i-1]和str2[j-1]是否相等,结果都是1 + dp[i-1][j-1],等于白写了这个条件
  2. 最核心的错误:当str1[i] != str2[j]时,你沿用了LCS的max(dp[i-1][j], dp[i][j-1])逻辑。但LCS的这个逻辑是为了保留之前不连续的最长匹配,而子串要求必须连续——一旦当前字符不匹配,当前位置的连续匹配就直接断裂了,根本不能继承之前的非连续结果。

正确的最长公共子串DP递推规则

我们重新定义dp[i][j]:以str1[i-1]和str2[j-1]结尾的最长公共子串的长度(这样处理边界更简单,当i=0或j=0时,dp[i][j] = 0,因为空字符串和任何字符串的公共子串长度都是0)。

递推规则如下:

  • 如果 str1[i-1] == str2[j-1]:dp[i][j] = dp[i-1][j-1] + 1
    (当前字符匹配,说明可以延续上一个位置的连续匹配长度)
  • 如果 str1[i-1] != str2[j-1]:dp[i][j] = 0
    (当前字符不匹配,连续子串直接断裂,当前位置的连续长度归0)

另外要注意:我们需要在填充DP表的全过程中,记录所有dp[i][j]里的最大值,这个最大值就是最长公共子串的长度。

举个简单例子验证

比如str1 = "abcde",str2 = "abxde":

  • 当i=2, j=2(对应字符'b'和'b'):dp[2][2] = dp[1][1] + 1 = 2(前一个字符'a'也匹配,连续长度累加)
  • 当i=3, j=3(对应字符'c'和'x'):dp[3][3] = 0(字符不匹配,连续断裂)
  • 当i=5, j=5(对应字符'e'和'e'):dp[5][5] = dp[4][4] + 1 = 2(前一个字符'd'匹配,连续长度从1变成2)

最终DP表中的最大值是2,对应最长公共子串"ab"或"de",完全符合预期。

内容的提问来源于stack exchange,提问作者Bernerd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:20:29