LeetCode第 516 题:最长回文子序列(C++)

516. 最长回文子序列 - 力扣(LeetCode)

在这里插入图片描述
不像第五题: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];
    }
};

猜你喜欢

转载自blog.csdn.net/qq_32523711/article/details/109104735