Leetcode——最长回文子序列

Posted Yawn,

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode——最长回文子序列相关的知识,希望对你有一定的参考价值。

1. 最长回文子序列

(1)动规

状态:

  • dp[i][j] 表示 s 的第 i 个字符到第 j 个字符组成的子串中,最长的回文序列长度是多少。

转移方程:

  • 如果 s 的第 i 个字符和第 j 个字符相同的话: dp[i][j] = dp[i + 1][j - 1] + 2
  • 如果 s 的第 i 个字符和第 j 个字符不同的话: dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
  • 然后注意遍历顺序,i 从最后一个字符开始往前遍历,j 从 i + 1 开始往后遍历,这样可以保证每个子问题都已经算好了。
    • 从递推公式dp[i][j] = dp[i + 1][j - 1] + 2 和 dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]) 可以看出,dp[i][j]是依赖于dp[i + 1][j - 1] 和 dp[i + 1][j],
    • 如果我们想求dp[i][j],那么其他3个必须都是已知的,很明显从上往下遍历是不行的,我们只能让i从最后一个字符往前遍历,j从i的下一个开始遍历,最后只需要返回dp[0][length - 1]即可。

初始化:

  • dp[i][i] = 1 单个字符的最长回文序列是 1
class Solution {
    public int longestPalindromeSubseq(String s) {
        int len = s.length();
        int[][] dp = new int[len][len];

        //这里i要从最后一个开始遍历
        for(int i = len-1; i >= 0; --i) {
            for(int j = i; j < len; ++j) {
                //单个字符也是一个回文串
                if(i == j) {
                    dp[i][j] = 1;
                    continue;
                } 
                //j从i的下一个开始
                if(s.charAt(i) == s.charAt(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];
    }
}

以上是关于Leetcode——最长回文子序列的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode刷题Python516. 最长回文子序列

Leetcode——最长回文子序列

Leetcode 516 最长回文子序列

516. 最长回文子序列(Python)

LeetCode 516 最长回文子序列[动态规划] HERODING的LeetCode之路

LeetCode 516. 最长回文子序列