方法:动态规划
主要分为以下两个步骤:
1、获取到两个字符串s1、s2在不同位置结尾的最长公共子序列长度,用一个二维数组dp将长度存储起来;
可以得到状态转移方程:
如果字符相等:dp[i][j] = 1 + dp[i - 1][j - 1];
如果字符不相等:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
2、从两个字符串的末尾向起点开始遍历,根据长度的大小来遍历,将得到的字符串进行反转即可得到最长的公共子序列。
时间复杂度:o(n2)
空间复杂度:o(n2)
class Solution { public: string LCS(string s1, string s2) { // 特殊情况处理 if (s1.length() == 0 || s2.length() == 0) return "-1"; int len1 = s1.length(); int len2 = s2.length(); // 存储在不同位置结尾的最长公共子序列长度 vector<vector<int> > dp(len1 + 1, vector<int> (len2 + 1, 0)); for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (s1[i - 1] == s2[j - 1]) dp[i][j] = 1 + dp[i - 1][j - 1]; else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); } } string res = ""; for (int i = len1, j = len2; dp[i][j] >= 1; ) { if (s1[i - 1] == s2[j - 1]) { res += s1[i - 1]; i--; j--; } else if (dp[i - 1][j] > dp[i][j - 1] ) { i--; } else { j--; } } reverse(res.begin(), res.end()); // 最长公共子序列为空 if (res.length() == 0) res = "-1"; return res; } };