最长公共子序列lcs定义与求解算法

最长公共子序列(LCS)的定义

最长公共子序列(Longest Common Subsequence,简称 LCS)是指在两个或多个序列中,找到一个最长的子序列,该子序列在所有输入序列中以相同的顺序出现,但不一定连续。

 

  • 例如:序列 “ABCBDAB” 和 “BDCAB” 的 LCS 是 “BCAB”(长度为 4),子序列中的元素顺序与原序列一致,但位置不要求连续。

LCS 的求解算法(动态规划)

动态规划是求解 LCS 的高效方法,核心思路是通过构建二维表格存储子问题的解,避免重复计算。

步骤 1:定义状态

设两个序列为X[0..m-1]Y[0..n-1],定义dp[i][j]表示X[0..i-1]Y[0..j-1]的 LCS 长度。

步骤 2:状态转移方程

  • X[i-1] == Y[j-1](当前元素相同),则dp[i][j] = dp[i-1][j-1] + 1(LCS 长度加 1)。
  • X[i-1] != Y[j-1](当前元素不同),则dp[i][j] = max(dp[i-1][j], dp[i][j-1])(取去掉 X 最后一个元素或 Y 最后一个元素后的 LCS 最大值)。

步骤 3:初始化

  • dp[0][j] = 0(X 为空序列时,LCS 长度为 0)。
  • dp[i][0] = 0(Y 为空序列时,LCS 长度为 0)。

步骤 4:回溯获取 LCS

通过填充后的dp表格,从dp[m][n]开始反向追溯:

 

  • X[i-1] == Y[j-1],则该元素是 LCS 的一部分,同时向左上方移动(i--, j--)。
  • 否则,向dp[i-1][j]dp[i][j-1]中值较大的方向移动(若相等,可任选其一)。

示例

X = "ABCBDAB"(长度 7)和Y = "BDCAB"(长度 5)为例:

 

  • 构建8x6dp表格(包含 0 行 0 列),填充后dp[7][5] = 4,即 LCS 长度为 4。
  • 回溯可得 LCS 为 “BCAB”(或 “BDAB”,因存在多个解)。

 

该算法时间复杂度为O(m*n),空间复杂度为O(m*n)(可优化为O(min(m,n)))。
posted @ 2025-08-30 13:35  CharyGao  阅读(98)  评论(0)    收藏  举报