516. 最长回文子序列

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。

示例 1:

输入:s = "bbbab"
输出:4
解释:一个可能的最长回文子序列为 "bbbb" 。

示例 2:

输入:s = "cbbd"
输出:2
解释:一个可能的最长回文子序列为 "bb" 。

提示:

  • 1 <= s.length <= 1000
  • s 仅由小写英文字母组成
class Solution {
public:
    int longestPalindromeSubseq(string s) {
        //如果 s[i] == s[j],且[i+1 - j-1]区间是回文字串,那么目前的总长度就是在原来的基础上+2; 想要求 [1,4],就得先知道[2,3]的情况。所以i方向
        
        //dp定义:dp[i][j]:[i-j]区间的最长回文子序列为 dp[i][j];
        vector>dp(s.size()+1,vector(s.size()+1,0));

        //递推关系:1、如果 s[i] == s[j]; 且那么 目前的最长长度为 dp[i+1][j-1]+2;
        //2、如果s[i] != s[j].那么最起码有 dp[i+1][j-1]这么长(继承)。再加上,分别考虑s[i]加入的情况 和 s[j]加入的情况。即:dp[i+1][j], dp[i][j-1];

        //初始化:如果 i==j,那么单个字符 也算一个回文串
        for(int i = 0;i < s.size();i++){
            dp[i][i] = 1;
        }

        //遍历顺序:想要求 [1,4],就得先知道[2,3]的情况。所以i方向从后往前。j方向从前往后。

        for(int i = s.size()-1;i >= 0;i--){
            for(int j = i+1;j < s.size();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][s.size()-1];
    }
};

你可能感兴趣的:(leetcode练习,c++,动态规划)