LeetCode-05最⻓的回文子串

该代码示例展示了如何在Java中找到一个字符串中最长的回文子串。它包括两种方法:暴力解法,通过检查所有子串来判断是否为回文,时间复杂度为O(n^3);以及扩展中心方法,通过迭代字符串并从可能的中心点向外扩展以找到最长回文串,时间复杂度为O(n^2)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**   给定⼀个字符串,输出最⻓的回文子串。回⽂串指的是正的读和反的读是⼀样的字符串,例如"aba","ccbbcc"。
 * 回文字符,需要判断
 * isPalindromic
 */
public class Test05 {
    public static void main(String[] args) {
        String maxPalindromicStr = "abcccbbccc";
        System.out.println("初始字符串:"+ maxPalindromicStr + ", 最长回文字符串:" + getMaxPalindromicStr01(maxPalindromicStr));
        System.out.println("初始字符串:"+ maxPalindromicStr + ", 最长回文字符串:" + longestPalindrome(maxPalindromicStr));

    }

    /**
     *  暴力解法, 找出原始字符串的所有字串, 2个指针, 双重移动, for^2
     *   对每个一个子串做 回文校验, 与其他回文字串的长度做比较, 记录较大值 for
     *   s.substring(i, j); 前开后闭
     *   保留子串的条件, 一 字串是回文字串, 二 字串的长度要大于最大值
     *
     *   时间复杂度:两层 for 循环 O(n²),for 循环⾥边判断是否为回⽂,O(n),所以时间复杂度为 O
     * (n³)。
     * 空间复杂度:O(1),常数个变量。
     * @param s
     * @return
     */
    private static String getMaxPalindromicStr01(String s) {
        String ans = "";
        int max = 0;
        int len = s.length();
        for (int i = 0; i < len; i++) {
            for (int j = i + 1; j <= len; j++) {
                String substring = s.substring(i, j);
                if (isPalindromic(substring) && substring.length() > max) {
                    ans = substring;
                    max = substring.length();
                }
            }

        }
        return ans;
    }

    /**
     *  判断字符串是否是回文子串
     * @return
     */
    private static boolean isPalindromic(String s) {
        int len = s.length(); // 字符串长度
        for (int i = 0; i < len/2; i++) {
            //游标i 和 len-1- i 处比较, 有对应关系
            if (s.charAt(i) != s.charAt(len-1 -i)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 扩展中⼼:
     *  我们知道回⽂串⼀定是对称的,所以我们可以每次循环选择⼀个中⼼,进⾏左右扩展,判断左右字符是否相
     * 等即可。
     * 扩展中心右2种选择   一、从⼀个字符开始扩展;  二、从两个字符之间开始扩展, 所以有 n + n-1 个中心
     */

    /**
     *
     * @param s
     * @return
     */
    public static String longestPalindrome(String s) {
        if (s == null || s.length() < 1) {
            return "";
        }
        int start = 0, end = 0;
        // 找出最大回文子串的2个下标
        for (int i = 0; i < s.length(); i++) {
            //扩展中心从一个字符开始
            int len1 = expandAroundCenter(s, i, i);
            //扩展中心从2个字符中间开始
            int len2 = expandAroundCenter(s, i, i + 1);
            // 回文的最大长度
            int len = Math.max(len1, len2);
            // 比较 记录的原始游标位置; 若大 需要更新位置
            if (len > end - start) {
                start = i - (len - 1) / 2; // 记录了 i变化时 回文字串的前后索引位置
                end = i + len / 2;
            }
        }
        return s.substring(start, end + 1); // 前开后闭 找出此最大的回文字符串
    }

    /**
     *  返回回文字符的长度
     * @param s 字符串
     * @param left 游标初始左位置
     * @param right 游标初始右位置
     * @return
     */
    private static int expandAroundCenter(String s, int left, int right) {
        int L = left, R = right;
        while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
            L--;
            R++;
        }
        return R - L - 1; // 可以获得回文字符的长度
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值