LeetCode-516. 最长回文子序列


题目来源

516. 最长回文子序列

题目详情

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

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

示例 1:

输入: s = "bbbab"
输出: 4
解释: 一个可能的最长回文子序列为 "bbbb" 。

示例 2:

输入: s = "cbbd"
输出: 2
解释: 一个可能的最长回文子序列为 "bb" 。

提示:

  • 1 <= s.length <= 1000
  • s 仅由小写英文字母组成

相似题目

题解分析

  1. 本题属于子序列的问题之一,问题的关键在于动态方程的定义,类似于最长回文子串的解法,我们dp 数组的定义是:在子串 s[i..j] 中,最长回文子序列的长度为 dp[i][j]。
  2. 状态转移方程如下:
    if (s[i] == s[j])
    	// 它俩一定在最长回文子序列中
    	dp[i][j] = dp[i + 1][j - 1] + 2;
    else
    	// s[i+1..j] 和 s[i..j-1] 谁的回文子序列更长?
    	dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
    
  3. 本题需要注意的一点是,如何确定遍历的方向?其实这个不难,我们只需要根据子结构来确定就好了,如根据dp[i+1][j-1]我们可以确定i一定是逆序遍历的,而j一定是正序遍历的。
class Solution {
    public int longestPalindromeSubseq(String s) {
        int n = s.length();
        // dp[i][j]表示(i, j)子串的最长回文子序列
        int[][] dp = new int[n][n];
        for(int i=0; i=0; i--){
            for(int j = i+1; j

参考

  1. 关于子序列问题,有一篇文章写的很好:https://mp.weixin.qq.com/s/zNai1pzXHeB2tQE6AdOXTA