Skip to main content

最长回文子序列

题目

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

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

提示:
  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成
示例
输入: s = "bbbab"
输出: 4
解释: 一个可能的最长回文子序列为 "bbbb"
输入: s = "cbbd"
输出: 2
解释: 一个可能的最长回文子序列为 "bb"

题解

对于一个子序列而言, 如果它是回文子序列, 并且长度大于 2, 那么将它首尾的两个字符去除之后, 它仍然是个回文子序列.

/**
* @param {string} s
* @return {number}
*/
var longestPalindromeSubseq = function (s) {
const n = s.length
const dp = new Array(n + 1).fill(0).map(() => new Array(n + 1).fill(0))

// 反着遍历保证正确的状态转移
for (let i = n - 1; i >= 0; i--) {
// 如果只有一个字符, 一定是回文
dp[i][i] = 1

const char1 = s[i]
for (let j = i + 1; j < n; j++) {
const char2 = s[j]
if (char1 === char2) {
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][n - 1]
}