leetcode题解5-最长回文子串

问题描述

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

示例 3:

输入:s = "a"
输出:"a"

示例 4:

输入:s = "ac"
输出:"a"
 

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成

解题思路

对于一个子串而言,如果它是回文串,并且长度大于 2,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串{"ababa’’},如果我们已经知道{“bab”} 是回文串,那么 {"ababa’’} 一定是回文串,这是因为它的首尾两个字母都是“a”。
根据这样的思路,我们就可以用动态规划的方法解决本题。
如果一个字符串的头尾两个字符都不相等,那么这个字符串一定不是回文串;
如果一个字符串的头尾两个字符相等,才有必要继续判断下去。

  • 如果里面的子串是回文,整体就是回文串;
  • 如果里面的子串不是回文串,整体就不是回文串。

即:在头尾字符相等的情况下,里面子串的回文性质据定了整个子串的回文性质,这就是状态转移。因此可以把「状态」定义为原字符串的一个子串是否为回文子串。
第 1 步:定义状态
dp[i][j] 表示子串 s[i…j] 是否为回文子串,这里子串 s[i…j] 定义为左闭右闭区间,可以取到 s[i] 和 s[j]。

第 2 步:思考状态转移方程
在这一步分类讨论(根据头尾字符是否相等),根据上面的分析得到:

dp[i][i] = (s[i]==s[j])   abd dp[i][j]				当j-i<=1时
dp[i][j] = (s[i] == s[j]) and dp[i + 1][j - 1]      当j-i>1

实现代码

class Solution {
    
    
    public String longestPalindrome(String s) {
    
    
        int n=s.length();
        char [] arrStr=s.toCharArray();     //将字符串转化为数组,便于运算
        int maxi=0,maxj=0;          //标记最长回文子串的下标
        int maxlen=0;
        //标记数组,标记从起点i到终点j之间的字符是否是回文子串,默认全为false
        boolean [][] f=new boolean[n][n];      
        //这里i是终点,j是i之前的字符,即以i为终点,遍历i之前的字符是否为回文子串
        //注意这里的顺序,一定要保证后面的回文子串利用到前面的回文子串时,前面的回文子串一定被计算出来过了。
        for(int i=0;i<n;i++){
    
    
            for(int j=0;j<=i;j++){
    
    
                //当i-j<=1时,判读那两个字符是否相等,相等即为回文子串,这里包含了i与j重合的情况
                if(i-j<=1){
    
    
                    if(arrStr[i]!=arrStr[j]){
    
    
                        f[j][i]=false;
                    }else{
    
    
                        f[j][i]=true;       //相等时如果大于当前最长回文子串的时候,就记录下来
                        if(maxlen<(i-j+1)){
    
    
                            maxlen=i-j+1;
                            maxi=i;
                            maxj=j;
                        }
                    }
                }else{
    
    
                    //当i-j>1时,需要判断当前两个字符是否相等,并且还要判断子字符串是否为回文子串。
                    if(arrStr[i]==arrStr[j] && f[j+1][i-1]==true){
    
    
                        f[j][i]=true;
                        if(maxlen<(i-j+1)){
    
    
                            maxlen=i-j+1;
                            maxi=i;
                            maxj=j;
                        }
                    }else{
    
    
                        f[j][i]=false;
                    }
                }
            }
        }
        String res="";
        for(int i=maxj;i<=maxi;i++){
    
    
            res+=arrStr[i];
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39736597/article/details/114524888