【LeetCode刷题】动态规划:5. 最长回文子串

在这里插入图片描述
方法一:暴力法
两次循环,判断两个字符以上的字符串是否是回文。
由于判断是否属于回文函数里又有一层循环,因此时间复杂度为O(N³),空间复杂度为O(1)。

class Solution {
    public String longestPalindrome(String s) {
        if(s.length()<2){
            return s;
        }
        int length = 1;
        int begin=0;
        char[] a = s.toCharArray();
        for (int i=0;i<a.length;i++){
            for(int j=i+1;j<a.length;j++){
                if(j-i+1>length&&isHuiWen(a,i,j)){
                    length=j-i+1;
                    begin = i;
                }
            }
        }
        return s.substring(begin,begin+length);
    }

    public boolean isHuiWen(char[] a,int x,int y){
        while(y>x){
            if(a[y]!=a[x]){
                return false;
            }
            x++;
            y--;
        }
        return true;
    }
}

方法二:动态规划(重要)

  • 定义状态
    dp[i][j] 表示子串 s[i…j] 是否为回文子串,这里子串 s[i…j] 定义为左闭右闭区间,可以取到 s[i] 和 s[j]。
  • 状态转移方程
    根据头尾字符是否相等
dp[i][j] = (s[i] == s[j]) and dp[i + 1][j - 1]
  • 边界条件是:表达式 [i + 1, j - 1] 不构成区间,即长度严格小于 2,即 j - 1 - (i + 1) + 1 < 2 ,整理得 j - i < 3。

如果子串 s[i + 1…j - 1] 只有 1 个字符,即去掉两头,剩下中间部分只有 11 个字符,显然是回文;
如果子串 s[i + 1…j - 1] 为空串,那么子串 s[i, j] 一定是回文子串。
因此,在 s[i] == s[j] 成立和 j - i < 3 的前提下,直接可以下结论,dp[i][j] = true,否则才执行状态转移。

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

代码:

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        if(len<2){
            return s;
        }
        int maxLength = 1;
        int begin=0;
        char[] a = s.toCharArray();
        boolean dp[][] = new boolean[len][len];

        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(a[i]!=a[j]){
                    dp[i][j]=false;
                }else{
                    if(j-i<3){
                        dp[i][j]=true;                   
                    }else{
                        // 等于去掉头尾的串的值
                        dp[i][j]=dp[i+1][j-1];
                    }
                }
                if(dp[i][j]==true&&j-i+1>maxLength){
                    maxLength=j-i+1;
                    begin=i;
                }
            }
        }
        return s.substring(begin,begin+maxLength); 
    }  
}
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页