Leetcode 5最长回文子串 Java

最长回文子串

题目:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

示例 2:
输入: “cbbd”
输出: “bb”

其实这道题的解法也是通过在网上搜别人的答案最后才完成的,并且只用了动态规划的办法,没有考虑更加适合的Manacher算法。本文只是记录一下我的发现错误/重新学习过程><

最开始的时候我考虑的是使用LCS的想法来做,只需考虑相等时dp[i][j]=dp[i-1][j-1]+1,而不用涉及到不等时取dp[i-1,j]和dp[i,j-1]的最大值。结果做出来通过了90+/110的样例,这还是很让我惊讶的…因为这道题用这样的解法有一个很致命的漏洞,例如输入为aacbfcaa,如果使用这种办法,输出为aac。然后我又自作聪明,想用递归来解决在aac中继续寻找最长回文串。结果显然又是不对的,例如abcdbbfcba

最后老老实实在网上找别人的DP思路。
参考链接:https://www.jianshu.com/p/a7741619dd58
(如有侵权,请联系我删除)

首先创建一个长宽都为 s.length() 的二维数组,boolean[][]dp,其中 dp[i][j] 表示字符串第i到j是否为回文。那么最开始的起点是j-i=1的都为true(我的理解是,相近的两个字符相等的时候)。之后状态转换如下,当字符串i所在的字符等于字符串j所在的字符,并且它的内部 dp[i+1][j-1] 为回文,那么dp[i][j]为true。因为这样的规律,我们要保证判断 dp[i][j] 的时候dp[i+1][j-1] 已经判断,所以我们遍历采用i降序j升序的嵌套遍历的方式

class Solution {
    public String longestPalindrome(String s) {
        if(s.length()==0)
        {
            return s;
        }
        int len=s.length();
        int left=0,right=0;
        boolean [][]num=new boolean[len][len];
        
        for(int i=len-2;i>=0;i--)
        {
            num[i][i]=true;
            for(int j=i+1;j<len;j++)
            {
                num[i][j]=s.charAt(i)==s.charAt(j)&&(j-i<3||num[i+1][j-1]);                             if(num[i][j]&&j-i>right-left)
                {
                    right=j;
                    left=i;
                }
            }
            
        }                
        return s.substring(left,right+1);
    }    
}

你可能感兴趣的:(Leetcode)