力扣---5.最长回文子串

题目描述:

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

示例1:

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

示例2:

输入: “cbbd”
输出: “bb”

解题思路:

首先观察回文数的特征,每一个回文字符串(长度大于)去掉头尾之后都是一个新的回文串,所以判断一个字符串是回文串,可以通过判定其去掉头尾部分是一个回文串,且头尾相同。由此,可以整理出动态规划的解决方案。设 dp[ i ][ j ] 为原字符串s从 索引i 到 j 的字符子串是否为回文子串(true Or false)。状态转移方程:dp[ i ][ j ] = dp[ i+1 ][ j-1 ] && s.toCharArray()[ i ] == s.toCharArray()[ j ]。
边界条件:

  1. dp[ i ][ i ]=true
  2. dp[ i ][ i+1 ]=(s.toCharArray()[ i ] == s.toCharArray()[ i+1 ]​ )
    因为使用了双重循环,所以时间复杂度为O(n2)
    代码:
	public static String longestPalindrome(String s) {
    
    
        int len = s.length();
        //前置判断,如果字符串长度为1,就直接返回该字符串
        if (len < 2){
    
    
            return s;
        }
        //maxLen用于记录最长回文子串的长度
        int maxLen = 1;
        //截取字符串起始位置
        int begin = 0;
        //设置边界条件
        boolean[][] dp = new boolean[len][len];
        for (int i = 0; i < len; i++) {
    
    
            dp[i][i] = true;
        }
        char[] chars = s.toCharArray();
        for (int j = 1; j < len; j++) {
    
    
            //二重循环,用i来寻找与j相同的元素,并做标记
            for (int i = 0; i < j; i++) {
    
    
                //状态转移方程的第一个判断,s.toCharArray()[i] == s.toCharArray()[j]
                if (chars[i] != chars[j]) {
    
    
                    dp[i][j] = false;
                } else {
    
    
                    //如果两个相等的字符之间只有一个字符,则这个子串也一定是回文子串
                    if (j - i < 3) {
    
    
                        dp[i][j] = true;
                    } else {
    
    
                        //转台转移方程的第二个判断,dp[i][j] = dp[i+1][j-1]
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }
                //重新标记回文子串的长度和起始位置,用于输出
                if (dp[i][j] && j - i + 1 > maxLen) {
    
    
                    maxLen = j - i + 1;
                    begin = i;
                }
            }
        }
        return s.substring(begin, begin + maxLen);
    }

猜你喜欢

转载自blog.csdn.net/TreeCode/article/details/108143792