题目
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
示例
输入:s = "bbbab" 输出:4 解释:一个可能的最长回文子序列为 "bbbb" 。
思路
图片来自代码随想录
可以看见,
①如果
s
的第i
个字符和第j
个字符相同的话dp[i][j] = dp[i+1][j-1] + 2
②如果
s
的第i
个字符和第j
个字符不相同的话1. s[i] 加入, s[j] 不加入:dp[i][j] = dp[i][j-1]
2. s[j] 加入, s[i] 不加入:dp[i][j] = dp[i-1][j]
注意:i必须递减,j必须递增,因为判断dp[i][j]的前提是知道dp[i+1][j-1]
所以求i必须知道i+1,i递减;求j必须知道j-1,j递增
且j>=i
答案
var longestPalindromeSubseq = function(s) {
// dp[i][j] 字符下标i到j所组成的字串的最长回文子序列长度 0<=i<j<=L-1
const L = s.length
const dp = new Array(L).fill(1).map(_=>new Array(L).fill(1))
//状态方程依赖左下 所以从左下开始遍历
for(i=L-2;i>=0;i--){
for(j=i+1;j<L;j++){
if(s[i]===s[j]){
dp[i][j] = j-i===1?2:dp[i+1][j-1]+2
}else{
dp[i][j] = Math.max(dp[i+1][j],dp[i][j-1])
}
}
}
// console.log(dp)
return dp[0][L-1]
};