leetcode第五题/JAVA

leetcode第五题/JAVA

最长回文子串

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

1.动态规划:时间复杂度O(n^2)

解题思路:标准动态规划思想解题,可以参考我的博客:动态规划算法思想和详解
首先需要思考的情况

  1. **什么是回文?**回文字符串即正读反读都相同的字符串,例如“aba”是回文,但“abc”不是。
  2. **回文如何使用动态规划思想?**假设我们判断一个长度为5的字符串是否是回文,我们可以将问题拆分为先判断长度为3的字符串是否是回文。如果长度为3的字符串不是回文,那长度为5的字符串一定不是回文,但是如果长度为3的是回文,我们只要判断长度为5的字符串的最外端是否是回文即可。
  3. **如何判断子串是否是回文?**假设我们现在需要判断s[i]-s[j]是否是回文,首先要判断s[i]==s[j],如果s[i]==s[j]则分为两种情况
  • s[i]到s[j]中间只有两个或者一个字符,即j-i<3。同时s[i] == s[j]。则s[i]-s[j]一定是回文串。
  • 如果s[i]到s[j]中间大于两个字符,我们只需要判断s[i+1]-s[j-1]是否为回文串即可,如果s[i+1]-s[j-1]是回文串,则s[i]-s[j]一定是回文串**(动态规划思想)**
  1. ** 如何储存子串是否是回文串**因为我们要储存s[i]-s[j]是否为回文串,所以我们可以定义一个boolean型的二维数组t_f[i][j]来储存s[i]-s[j]是否是回文串。
public String longestPalindrome(String s) {
        int s_len = s.length();
        //left是回文左边的下标,right是回文右边下标,len是回文长度
        int left = 0,right = 0,len = 0;
        //用来储存s[i]-s[j](t_f[i][j])是否是回文
        boolean [][] t_f = new boolean[s_len][s_len];
        //遍历数组
        for(int i=0;i<s_len;i++){
            //一个字母一定构成回文
            t_f[i][i] = true;
            for(int j=i;j>=0;j--){
                //如果i,j一致则有可能是回文串
                if(s.charAt(i) == s.charAt(j)){
                    //如果i,j中间小于3个字符且s[i]==s[j],例如aba或者bb,则一定是回文
                    if( i - j < 3){
                        t_f[j][i] = true;
                    }else{
                        //如果i-j>3,如果s[i+1][j-1]是回文,则,s[j]-s[i]是回文
                        t_f[j][i] = t_f[j+1][i-1];
                    }
                }else{
                    t_f[j][i] = false;
                }
                //判断是否大于前一个回文串。
                if( t_f[j][i] == true ){
                    int temp = i+1 - j;
                    if(temp > len){
                        len = temp;
                        left = j;
                        right = left + temp;
                    }
                }
            }
        }
        return s.substring(left,right);
    }
}

最后附上我的leetcode刷题目录leetcode刷题目录

你可能感兴趣的:(leetcode刷题)