首页 > 代码库 > 最长回文子序列

最长回文子序列

题目:给你一个字符串,求它的最长回文子序列,比如“bbbab” 最长回文子序列是"bbbb" 所以返回4,,"abab"最长子序列是“aba”或者“bab” 所以返回3

思路:和之前做的几道dp不同,,,也是我不够变通,,打dp表的时候总习惯左上到右下的顺序,但是这个顺序却固化了我的思维,忽略了对于题解本身含义的理解。。。。。。。

这个题从下到上开始打表,最重要的是它的含义,,,知道dp[i][j]意味着什么,就自然理解了题目的思路,,明白了为什么这么做。。。。本题中dp[i][j]的含义是原字符串从第i位到第j位可以构成最长回文子序列的长度。。。。str(i)==str(j)的时候,dp[i][j]=dp[i+1][j-1]+2,,为什么呢,比如"bbbab” i是0,j是4 dp[i][j]就是第一位到最后一位可以构成回文子序列的长度,它等于第二位(i=1)和倒数第二位(j=3)之间的字符串可以构成最长回文子序列的长度+2,也就是ba之间可以构成最长回文子序列的长度加上前后两个a,如果str(i)!=str(j),那么dp[i][j]就等于第i-1到j位和第i位到j+1这两个区间的最长回文子序列长度,,比如“bbbac”,i=0,j=4;第一位不等于最后一位,那么dp[i][j]就等于1到4或者0到3这两个区间的最长回文子序列长度中比较大的那个,,,为什么呢,,,既然第一位不等于最后一位,那么换个思路,第一位到最后一位之间的最长回文子序列不就和删去第一位或最后一位之后剩下区间的最长子序列长度一样么。。。。。。

 

 public int longestPalindromeSubseq(String s) {
        int n=s.length();
        int[][] dp = new int[n][n];
       for (int i = s.length() - 1; i >= 0; i--) {
            dp[i][i] = 1;
            for (int j = i+1; j < s.length(); 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];
    }

 

最长回文子序列