给你一个字符串 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<vector<int>>dp(s.size()+1,vector<int>(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];}
};