【刷题1】LeetCode 5. 最长回文子串 java题解

1.题目

在这里插入图片描述

2.方法一:暴力

时间复杂度O(N的三次方):这里 N 是字符串的长度,枚举字符串的左边界、右边界,然后继续验证子串是否是回文子串,这三种操作都与N相关;
空间复杂度:O(1),只使用到常数个临时变量,与字符串长度无关。

3.方法二:动态规划

3.1 分析

初始状态dp[i][i]=true。
如果c[i]!=c[j],返回false;
如果c[i]==c[j],要看i和j之间字串是不是回文串,如果字串也是,dp[i][j]=true。(转移方程dp[i][j]=dp[i+1][j-1])
边界情况:[i+1][j-1]长度小于等于1(即j-i<3),dp[i][j]必定为true。

保存结果:起始下标beginIndex和回文串长度maxLength。这样可以省去每次截取字串消耗的时间。等返回时再截取最终结果。

3.2 代码

class Solution {
    public String longestPalindrome(String s) {
        int len=s.length();
        if(len<2)
            return s;
        char[] charArray=s.toCharArray();
        boolean[][] dp=new boolean[len][len]; 
        int maxLength=1;//最长回文串的长度
        int begin=0;//最长回文串的起始下标
        //初始化
        for(int i=0;i<len;i++){
            dp[i][i]=true;
        }
        for(int j=1;j<len;j++){
            for(int i=0;i<j;i++){
                if(charArray[i]!=charArray[j]){
                    dp[i][j]=false;
                    continue;
                }
                if((j-i)<3){
                    dp[i][j]=true;
                }
                else{
                    dp[i][j]=dp[i+1][j-1];
                }
                if((j-i+1)>maxLength&&dp[i][j]){
                    maxLength=j-i+1;
                    begin=i;
                }
            }
        }
        return s.substring(begin,begin+maxLength);
    }
}

3.3 复杂度

时间复杂度O(N²)
空间复杂度O(N²)

3.4 结果

在这里插入图片描述

4.方法三:中心扩散法

4.1 思路

边界情况即为子串长度为 1或 2的情况。我们枚举每一种边界情况,并从对应的子串开始不断地向两边扩展。如果两边的字母相同,我们就可以继续扩展,例如从 P(i+1,j-1) 扩展到 P(i,j);如果两边的字母不同,我们就可以停止扩展,因为在这之后的子串都不能是回文串了。

4.2 代码

class Solution {
    String s;
    public String longestPalindrome(String s) {
        this.s=s;
        if(s==null||s.length()<1)
            return "";

        int begin=0,end=0;
        for(int i=0;i<s.length();i++){
            int len1=expand(i,i);
            int len2=expand(i,i+1);
            int len=Math.max(len1,len2);
            if(len>end-begin){
                begin=i-(len-1)/2;
                end=i+len/2;
            }
        }
        return s.substring(begin,end+1);
    }
    public int expand(int left,int right){
        while(left>=0&&right<s.length()&&s.charAt(left)==s.charAt(right)){
            --left;
            ++right;
        }
        return right-left-1;
    }
}

4.3 复杂度

时间复杂度:O(n^2)。其中 n是字符串的长度。长度为 1和 2 的回文中心分别有 n 和 n−1 个,每个回文中心最多会向外扩展O(n) 次。
空间复杂度:O(1)。

4.4 结果

在这里插入图片描述

5.方法四:Manacher 算法

太难了,我跳过。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页