问题描述:
给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000。

示例 1:
输入:

“bbbab”
输出:

4
一个可能的最长回文子序列为 “bbbb”。

示例 2:
输入:

“cbbd”
输出:

2
一个可能的最长回文子序列为 “bb”。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-subsequence

//利用一个二维数组:
class Solution {
public int longestPalindromeSubseq(String s) {
int n = s.length();
char[] chars = s.toCharArray();
//dp[i][j]表示从i~j范围内的最长回文串长度
int dp[][] = new int[n][n];
//初始化dp数组,单个字符的回文串是1
for(int i=0;i<n;i++){
dp[i][i]=1;
}
//从长度为2,开始扩大范围扫描
for(int len=2;len<=n;len++){
for(int i=0;i<n-len+1;i++){
int j = i+len-1;
//首尾字符相等,就在原来的长度基础上加2
if(chars[j]==chars[i]){
dp[i][j] =2+(len==2?0:dp[i+1][j-1]);
}else{
//不相等就是更小范围的最长回文长度
dp[i][j] = Math.max(dp[i][j-1],dp[i+1][j]);
}
}
}
return dp[0][n-1];
}
}

//优化:利用一维数组

class Solution {
public int longestPalindromeSubseq(String s) {
int len = s.length();
int dp[] = new int [len];

char[] chars = s.toCharArray();
int i,j,max;
for(j=0;j<len;j++){
dp[j]=1;
max = 0;
for(i=j-1;i>-1;i--){
int tmp = dp[i];//保存上一趟的dp[i]

if(chars[j]==chars[i])dp[i] = max +2;

max = Math.max(tmp,max);//更新当前(0~j-1)的最长回文子序列长度
}
}
max = 0;
//比较dp数组中最长的回文子序列长度
for(i = 0;i<len;i++){
max = Math.max(max,dp[i]);
}

return max;
}
}