不像第五题:LeetCode第 5 题:最长回文子串(C++)_zj-CSDN博客
这儿的回文子序列是不需要连续的。这题其实是dp的思路去做,不过这一题的dp有点特殊
参考这儿的图;子序列问题通用思路|最长回文子序列 - 最长回文子序列 - 力扣(LeetCode)
if (s[i] == s[j])
// 它俩一定在最长回文子序列中
dp[i][j] = dp[i + 1][j - 1] + 2;
else
// s[i+1..j] 和 s[i..j-1] 谁的回文子序列更长?
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
所以计算dp[i][j]的时候,需要大于i的都已经计算好,小于j的也都已经计算好,所以需要逆序遍历i,正序遍历j。
i 从最后一个字符开始往前遍历,j 从 i + 1 开始往后遍历,这样可以保证每个子问题都已经算好了。
初始化就是dp[i][i] = 1,其他的都为0就可以了
class Solution {
public:
int dp[1010][1010];//dp[i][j]表示s[i..j]代表的字符串的最长回文子序列
int longestPalindromeSubseq(string s) {
int n = s.size();
for(int i = 0; i < n; ++i) dp[i][i] = 1;
for(int i = n-1; i >= 0; --i){
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];
}
};