二刷516. Longest Palindromic Subsequence

Medium
实践证明,第一次没有彻底搞懂的题,第二次你还是会卡在 一样的地方。这道题当时我的记录是这样的:

二刷516. Longest Palindromic Subsequence_第1张图片
image.png

我二刷卡在了index为什么要倒着走那里,结果我当时只写一句:不这么写的话后面会很麻烦。 这就是不理解还硬用,尴尬吧。还是要搞扎实一点啊,同学。

简单解释一下吧。因为后面我们求dp[i][j]需要用到dp[i+1][j-1],dp[i+1][j], dp[i][j-1] 所以很明显我们的i需要从大到小,j需要从小到大来遍历。那i肯定最大是n-1,但j最小是不是0呢?肯定不是,随时记得dp方程表示的含义:dp[i][j]表示substring[i,j] (inclusively)所有最长回文子序列的长度,所以substring[i, j]确定了j至少得大于等于i。又因为我们单独处理了j== i的情况,所以j从i+1开始。而且这里我们为什么要把dp[i][i]单独提出来说呢?这是由于这个dp方程所代表的特殊含义决定的,我们不能用一般的转换方程去处理dp[i][i], 因为它代表的substring就是一个单独的char.

class Solution {
    public int longestPalindromeSubseq(String s) {
        if (s == null || s.length() == 0){
            return 0;
        }
        int n = s.length();
        //dp[i][j]: the length of the longest palindrome subsequence in substring[i, j] (inclusively)
        int[][] dp = new int[n][n];
        for (int i = n - 1; i >= 0; i--){
            dp[i][i] = 1;
            //substring[i,j] stands for substring starting from i and ending at j both inclusively
            //it's intuitive that j is equals to or greater than i, and since we 
            //speciafically talked about dp[i][i], j is sure to be greater than i in the inner for loop.
            for (int j = i + 1; j < n; j++){
                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][n - 1];
    }
}

你可能感兴趣的:(二刷516. Longest Palindromic Subsequence)