LeetCode 516.最长回文子序列
思路:回文子序列和LCS的做法比较相似,s[i] = s[j] 时,状态转移方程为 dp[i][j] = dp[i + 1][j - 1] + 2。 否则为 dp[i][j] = max{dp[i + 1][j], dp[i][j - 1]} 即不选 s[i] 或者不选 s[j]。
dp[i][j] 代表从 s[i] 到 s[j] 的回文子序列最大长度,可知 i 的转移顺序从 n - 1 到 0,j 的转移顺序从 i + 1 到 n - 1。
本题可以进行空间优化,代码如下。
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n = s.size();
vector<vector<int>> dp(n, vector<int>(n, 0));
for(int i = n - 1; i >= 0; i--) {
dp[i][i] = 1;
for(int j = i + 1; j < n; j++) {
if(s[i] == s[j])
dp[i][j] = dp[i + 1][j - 1] + 2;
else
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}
}
return dp[0][n - 1];
}
};
//空间优化
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n = s.size();
vector<int> dp(n, 0);
for(int i = n - 1; i >= 0; i--) {
dp[i] = 1;
int pre = 0;
for(int j = i + 1; j < n; j++) {
int temp = dp[j];
if(s[i] == s[j])
dp[j] = pre + 2;
else
dp[j] = max(dp[j], dp[j - 1]);
pre = temp;
}
}
return dp[n - 1];
}
};