第一步,通过动态规划找到最长公共子序列长度,并构建dp数组:dp[i][j]:s1[i]和s2[j]为止的最长公共子序列的长度。dp[0][0] = s1[0] == s2[0]dp[i][0] = s1[i] == s2[0] ? 1 : dp[i - 1][0]dp[0][i] = s1[0] == s2[i] ? 1 : dp[0][i - 1]dp[i][j] = dp[i - 1][j - 1] + 1, s1[i] == s2[j]dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]), s1[i] != s2[j]
第二步,根据dp反推最长公共子序列内容。
class Solution {
public:
string LCS(string s1, string s2) {
if(s1.empty() || s2.empty()) return "-1";
int len1 = s1.size(), len2= s2.size();
int dp[len1][len2];
dp[0][0] = s1[0] == s2[0];
for(int i = 1; i < len1; i++)
dp[i][0] = s1[i] == s2[0] ? 1 : dp[i - 1][0];
for(int i = 1; i < len2; i++)
dp[0][i] = s1[0] == s2[i] ? 1 : dp[0][i - 1];
for(int i = 1; i < len1; i++)
{
for(int j = 1; j < len2; j++)
{
if(s1[i] == s2[j])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
}
}
string ans = "";
for(int i = len1 - 1, j = len2 - 1; i >= 0 && j >= 0;)
{
if(s1[i] == s2[j])
{
ans += s1[i];
i--, j--;
}
else if(j == 0 || dp[i - 1][j] > dp[i][j - 1]) i--;
else if(i == 0 || dp[i][j - 1] >= dp[i - 1][j]) j--;
}
reverse(ans.begin(), ans.end());
return ans.size() == 0 ? "-1" : ans;
}
};


京公网安备 11010502036488号