二维 DP:字符相等时 dp[i][j]=dp[i-1][j-1]+1,不等时取 max(dp[i-1][j], dp[i][j-1])。
OJ: leetcodecn
题目 ID: longest-common-subsequence
难度:普及+/提高
标签:动态规划字符串
日期: 2026-07-29 12:57
题意
求两个字符串的最长公共子序列长度。
思路
dp[i][j] 表示 text1[0..i-1] 和 text2[0..j-1] 的 LCS 长度。若 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])。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int longestCommonSubsequence(string a, string b) {
int m = a.size(), n = b.size();
vector<int> dp(n + 1, 0);
for (int i = 1; i <= m; i++) {
int prev = 0;
for (int j = 1; j <= n; j++) {
int tmp = dp[j];
if (a[i - 1] == b[j - 1])
dp[j] = prev + 1;
else
dp[j] = max(dp[j], dp[j - 1]);
prev = tmp;
}
}
return dp[n];
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string a, b;
cin >> a >> b;
cout << Solution().longestCommonSubsequence(a, b) << '\n';
return 0;
}python
#!/usr/bin/env python3
class Solution:
def longestCommonSubsequence(self, a: str, b: str) -> int:
m, n = len(a), len(b)
dp = [0] * (n + 1)
for i in range(1, m + 1):
prev = 0
for j in range(1, n + 1):
tmp = dp[j]
if a[i - 1] == b[j - 1]:
dp[j] = prev + 1
else:
dp[j] = max(dp[j], dp[j - 1])
prev = tmp
return dp[n]
def main():
a = input().strip()
b = input().strip()
print(Solution().longestCommonSubsequence(a, b))
if __name__ == "__main__":
main()复杂度
- 时间复杂度:
。 - 空间复杂度:
。
总结
LCS 是二维 DP 的经典:相等时沿对角线延伸,不等时取上方或左方的较大值。