力扣练习之最长回文子串

我爱海鲸 2023-01-17 14:40:02 力扣

简介中级算法、最长回文子串

原题出处:https://leetcode.cn/leetbook/read/top-interview-questions-medium/xvn3ke/

解法一(不建议使用,只提供思路):

class Solution {
    public String longestPalindrome(String s) {
        String str = s;
        if (isbool(str)) {
            return str;
        }
        // 除去最后一个字符
        String str1 = str.substring(0,str.length()-1);
        if (isbool(str1)) {
            return str1;
        } 
        String result1 = longestPalindrome(str1);
        // 除去第一个字符
        String str2 = str.substring(1,str.length());
        if (isbool(str2)) {
            return str2;
        }
        String result2 = longestPalindrome(str2);
        // 除去第一个和最后一个字符
        String str3 = str.substring(1,str.length()-1);
        if (isbool(str3)) {
            return str3;
        }
        String result3 = longestPalindrome(str3);
        return getStr(result1,result2,result3);
    }

    private boolean isbool(String s) {
        int length = s.length()/2;
        char[] chars = s.toCharArray();
        for (int i = 0 ; i < length; i++) {
            char c = chars[i];
            char cLast = chars[chars.length-1-i];
            if (c != cLast) {
                return false;
            }
        }
        return true;
    }

    private String getStr(String str1,String str2,String str3) {
        int len1 = str1.length();
        int len2 = str2.length();
        int len3 = str3.length();
        int max = len1;
        if (max < len2) {
            max = len2;
        }
        if (max < len3) {
            max = len3;
        }
        if (max == len2) {
            return str2;
        }
        if (max == len3) {
            return str3;
        }
        return str1;
    }
}

思路:首先写一个验证是否是回文串的方法,可以参考力扣练习之验证回文串  

然后就是递归的思路,将字符串递归判断是否是一个回文串,每次递归都要将字符串的第一个字符或者最后一个字符或者第一个和最后一个字符切割除去,还需要一个方法判断递归后,那个切割方式返回的最大回文串最长然后返回即可。

但是方法会进行大量的递归操作,会导致超时,所以不建议使用该种方法,这里只提供一个思路。

解法二:

class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() < 1) return "";
        int start = 0, end = 0;
        for (int i = 0; i < s.length(); i++) {
            int len1 = expandAroundCenter(s, i, i);
            int len2 = expandAroundCenter(s, i, i + 1);
            int len = Math.max(len1, len2);
            if (len > end - start) {
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }
        return s.substring(start, end + 1);
    }

    private int expandAroundCenter(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        return right - left - 1;
    }
}

思路:Manacher 算法,该算法的思想是从字符串的每一个字符开始,向两边扩展,找到最长的回文子串。这里有一点需要注意的是回文串可能是奇数,也可能是偶数,如果是奇数,那么中间就是一个单个的字符,如果是偶数,那么中间就是两个相同的字符,

所以我们在算法中需要注意一个获取奇数的回文串长度,一个获取偶数的回文串长度,取其中较大的一个值,获取字符串元素中的起始下标和结束下标,最后分割字符串即可。

你好:我的2025