5.Longest Palindromic Substring(动态规划)

我凑!!!终于吃下了这道动态规划
leetcode link

Example 1:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:
Input: "cbbd"
Output: "bb"

动态规划:最终结果依靠子结果,子结果依靠子子结果,以此免去重复计算。所以子结果必须在最终结果之前计算并保存下来,而且最下层、也就是最先计算的子子子...结果就是动态规划的边界。

本道题中,以babad为例,如果babad是回文串,则需要满足两个条件:
1.首末两个字符相同,即 b == d;
2.去掉首末两个字符,中间的字串(aba)也是回文串。
以此可以得出状态转移方程:P(i,j) = s[i]==s[j] && P(i+1,j-1);
3.当i=j,P(i,j)一定回文;
当i+1=j, 如果s[i]==s[j]也满足回文;
而上述两种情况构成了这道题的边界条件。

实现:
1.先判断s.length 为0和1的情况。
2.构建boolean类型的二维数组存放子结果。以babad为例,这道题最终需要求P(0,4),而P(0,4)不仅取决于s[0]==s[4],还取决于子结果P(1,3),而P(1,3)取决于s[1]==s[3] 和P(2,2).也就是说,二维数组中,结果集位于dp[0,0] 到dp[4,4]的右上方区域(包含dp[0,0],dp[1,1],,,);而获取子结果的方向是横坐标向下,纵坐标向左,也就是向左下方获取子结果,所以我们需要以dp[0,0]到dp[4,4]的线为底线,向右上方的方向不断获取父结果(如图)

dp[][]

3.要实现步骤2的方向,也就是蓝线->绿线->黄线,需要控制i与j的差值gap逐渐增大,蓝线gap=0,求出dp[0,0]、dp[1,1]、dp[2,2]、、;绿线gap=1,求出dp[0,1]、dp[1,2]、dp[2,3]、、直到最后gap=4,求出最后一格dp[0,4]。而每次求出true时,gap+1就是当前这次结果的回文子串长度,用一个新的String记录,每次为true时,如果超出原本长度则更新即可。(注意,随着gap的逐渐增大,每轮比较的组数逐渐减小,图中可见篮绿黄线逐渐变短)。

Java代码实现:

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        if(len == 0 || len == 1){
            return s;
        }
        String ans = "";
        boolean[][] dp = new boolean[len][len];
        for(int gap = 0; gap ans.length())){
                    ans = s.substring(i,j+1);
                }
            }
        }
        return ans;
    }
}

你可能感兴趣的:(5.Longest Palindromic Substring(动态规划))