题解 | #最长公共子序列(二)#
最长公共子序列(二)
https://www.nowcoder.com/practice/6d29638c85bb4ffd80c020fe244baf11
class Solution {
public:
/**
* longest common subsequence
* @param s1 string字符串 the string
* @param s2 string字符串 the string
* @return string字符串
*/
/*
注解:子序列不需要连续,子串需要连续。
1、求最长公共子序列长度 dp[i][j]:表示:s1[1-i]的子序列,s2[1-j]的子序列 的最长公共数
2、我们在dp求最长公共数时,用一个数组PII pre[i][j] 存储当前状态[i,j]是由那个位置转移的
3、最后,我们从最后m-1,n-1倒叙开始找到公共子序列,直到i=0||j=0,
4、返回reverse(s.begin(),s.end());
*/
string LCS(string s1, string s2) {
// write code here
s1 = " " + s1, s2 = " " + s2;
int m = s1.size(), n = s2.size();
//dp[i][j] 表示s1[i]前i个子序列和s2[j]的前j个子序列的最长公共
vector<vector<int>>dp(m, vector<int>(n, 0));
string s = "";
vector<vector<pair<int, int>>>pre(m, vector<pair<int, int>>(n, {0, 0}));
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (s1[i] == s2[j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
pre[i][j] = {i - 1, j - 1};
} else {
if (dp[i - 1][j] > dp[i][j - 1]) {
pre[i][j] = {i - 1, j};
} else {
pre[i][j] = {i, j - 1};
}
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
if (!dp[m - 1][n - 1]) return "-1";
int i = m - 1, j = n - 1;
while (i != 0 && j != 0) {
if (s1[i] == s2[j]) {
s += s1[i];
}
auto [pi, pj] = pre[i][j];
i = pi,j = pj;
}
reverse(s.begin(),s.end());
return s;
}
};



海康威视公司福利 1182人发布