C++标准库无std::lcs,必须手写二维DP:dpi表示text1[0..i-1]与text2[0..j-1]的LCS长度,开(m+1)×(n+1)表并初始化首行首列为0;字符相等时dpi=dpi-1+1,否则取max(dpi-1, dpi);还原字符串需逆向回溯并反转结果。

为什么不能直接用 std::lcs?
C++ 标准库根本不存在 std::lcs 或任何内置 LCS 函数。这是常见误解,尤其刚从 Python( difflib)或 Java(Apache Commons)转过来的人容易踩坑。LCS 是经典动态规划问题,必须手写逻辑,没有捷径。
二维 DP 数组怎么初始化和填表?
核心是定义 dp[i][j] 表示 text1[0..i-1] 和 text2[0..j-1] 的 LCS 长度。注意下标偏移:长度为 m 和 n 的字符串,DP 表要开 (m+1) × (n+1),首行首列全初始化为 0 —— 这是为了统一处理边界(比如一个字符串为空时 LCS=0)。
状态转移只两种情况:
- 若
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])
别漏掉 i-1 和 j-1——这是最容易写错的下标越界点。
立即学习“C++免费学习笔记(深入)”;
怎么还原 LCS 字符串而不是只返回长度?
只存长度的 DP 表无法回溯构造结果。必须额外记录决策路径,或在填完表后从 dp[m][n] 开始逆向追踪:
- 从
i = m, j = n出发,往左上走 - 若
text1[i-1] == text2[j-1],该字符属于 LCS,加入结果,然后i--, j-- - 否则比较
dp[i-1][j]和dp[i][j-1],往值更大的方向走(相等时任选其一) - 最后把结果字符串反转
注意:不反转就得到逆序 LCS,这是初学者常忽略的细节。
空间能优化到 O(min(m,n)) 吗?
可以,但仅限求长度。因为 dp[i][j] 只依赖上一行和左边格子,用滚动数组即可:dp[2][n+1] 或单个一维数组 prev[j] + curr[j]。但一旦要还原字符串,就必须保留完整二维表或至少保存整个路径信息——空间退回到 O(m×n)。
实际项目中如果字符串很长(比如 >10k 字符),要考虑用 Hunt–Szymanski 算法(基于 LCS 与 LIS 的等价性),但那是另一套实现逻辑了。


















