516.最长回文子序列

一.  leetcode题目链接

https://leetcode-cn.com/problems/longest-palindromic-subsequence/

二.  动态规划

  1. 样本:cabbeaf
  2. 状态转移

(1) 如果一个字符串S[0,1,2,3,,,n-1],S[0] == S[n-1]那么最大回文子序列就是

  P(left,right) = P(left+1,right-1) + 2 left表示字符串的起点,right表示字符串 的终点)

(2) 如果这个字符串S[0]!= S[n-1]

  P(left,right) = max{ P(left+1,right),p(left,right-1)}

  1. 边界

字符串长度为1 的最大回文子串长度为1

  1. 例子

下图表示,从dp[left][right]这个区间的字符串的最大回文是多大,

  比如dp[0][3]表示”cabb”的最大回文子序列长度是2

  比如dp[1][1]表示”a”的最大回文子序列长度是1

初始化,所有dp[i][i]的回文子序列长度是自己本身,所以是1,(蓝色底部)

开始动态规划程序:(从左下到右上,按照长度为2 的字符串,长度为3,4,5,依次增加)

 

程序:

 public int longestPalindromeSubseq(String s) {
        if (s.length() == 0 || s == null) {
            return 0;
        }
        int length = s.length();
        char[] str = s.toCharArray();
        int[][] dp = new int[length][length];
        for (int i = 0; i < length; i++) {
            dp[i][i] = 1;
        }
        //String maxStr = s.substring(0,0);
        for (int i = 1; i < length; ++i) {
            int tmp = 0;
            for (int j = 0; j + i < length; ++j) {
                if (str[j] == str[i + j]) {
                    tmp = dp[j + 1][i + j - 1] + 2;
                    //这个记录了最大的子序列,本题中没用过
                    //maxStr = str[j] + maxStr + str[j];
                } else {
                    tmp = Math.max(dp[j + 1][i + j], dp[j][i + j - 1]);
                }
                dp[j][j + i] = tmp;

            }
        }

        return dp[0][length - 1];
    }

 

posted @ 2019-10-07 21:19  式微胡不归  阅读(274)  评论(0编辑  收藏  举报