1. 题目描述
给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。
示例 1:
输入: "bbbab"输出: 4一个可能的最长回文子序列为 "bbbb"。
示例 2:
输入: "cbbd"输出: 2一个可能的最长回文子序列为 "bb"。
提示:
这里我们尝试使用动态规划来解答,初始化一个dp二维数组来保存子串的长度,dp[i][j]表示s中的第i个字符到第j个字符组成的子串中,最长的回文序列的长度。
下面最重要的就是找出状态转移方程:
- 如果字符串s的第i个和第j个字符相同:
f[i][j] = f[i + 1][j - 1] + 2 - 如果字符串s的第i个和第j个字符不相同:
f[i][j] = max(f[i + 1][j], f[i][j - 1])
这里需要注意遍历时的顺序,i是从最后一个字符开始遍历的,j是从i+1开始向后遍历,这样就能保证每个子问题都计算好了。最后只要返回dp[0][len-1]即可。
复杂度分析:
- 时间复杂度:O(n),其中n是字符串的长度,我们需要一个双层的遍历;
空间复杂度:O(n),其中n是字符串的长度,我们需要初始化一个二维数组。
3. 代码实现
/*** @param {string} s* @return {number}*/var longestPalindromeSubseq = function(s) {let len = s.length;let dp = new Array(len)for (let i = 0; i < len; i++) {dp[i] = new Array(len).fill(0);}for (let i = len - 1; i >= 0; i--) {dp[i][i] = 1;for (let j = i+1; j < len; j++) {if (s[i] === s[j]) {dp[i][j] = dp[i+1][j-1] + 2;} else {dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1])}}}return dp[0][len-1];};
4. 提交结果

