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 仅由数字和英文字母(大写和/或小写)组成

1、暴力解法

遍历所有的子串,并判断每一个子串是否为回文串,最后即可得到最长的回文子串。

class Solution {
    public String longestPalindrome(String s) {
        int length = s.length();
        int maxLength = 0;
        String res = "";
        for(int subLength = 1; subLength <= length; subLength++){
            for(int index = 0; index + subLength <= length; index++){
                String subStr = s.substring(index, index + subLength);
                if(isPalindrome(subStr)){
                    if(subStr.length() > maxLength){
                        maxLength = subStr.length();
                        res = "" + subStr;
                    }
                }
            }
        }
        return res;
    }

    public boolean isPalindrome(String s){
        int length = s.length();
        int left = 0;
        int right = length - 1;
        while(left <= right){
            if(s.charAt(left) != s.charAt(right)){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

两层for循环进行两次遍历,判断回文串也要进行一次遍历,则时间复杂度达到了O(n³),直接提交会超时。但是参考官方题解,暴力解法也是能通过的。在以上解法中每判断一次回文子串都需要截取一次字符串,会有额外的性能消耗,则不再截取字符串,只记录最长回文子串的起始位置和长度,最后返回的时候再截取子串。当字符串长度为1时不需要判断直接返回即可。进行剪枝操作后可勉强通过。

//执行用时:2850 ms
class Solution {
    public String longestPalindrome(String s) {
        int length = s.length();
        if(length < 2){
            return s;
        }
        int maxLength = 1;
        int resLeft = 0;
        for(int subLength = 2; subLength <= length; subLength++){
            for(int index = 0; index < length - subLength + 1; index++){
                if(isPalindrome(s, index, index + subLength - 1)){
                    if(subLength > maxLength){
                        maxLength = subLength;
                        resLeft = index;
                    }
                }
            }
        }
        return s.substring(resLeft, resLeft + maxLength);
    }

    public boolean isPalindrome(String s, int left, int right){
        int indexL = left;
        int indexR = right;
        while(indexL <= indexR){
            if(s.charAt(indexL) != s.charAt(indexR)){
                return false;
            }
            indexL++;
            indexR--;
        }
        return true;
    }
}

时间复杂度:O(n³)
空间复杂度:O(1),仅消耗常数空间

2、动态规划

你可能感兴趣的:(leetcode刷题日记——5. 最长回文子串)