🧠 枚举回文中心,用左右指针向两边扩散,专治一切回文相关问题。

🧩 模板步骤

枚举中心位置 i

以 (i, i) 作为中心(奇数回文)

以 (i, i + 1) 作为中心(偶数回文)

左右指针同时扩散:left–、right++

越界或不相等立即停止

⭐ 模板

  1. 中心扩散函数

    // 从中心 left, right 开始向两边扩散
    private int expand(String s, int left, int right) {
    while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
    left–;
    right++;
    }

    // 返回当前回文长度
    return right - left - 1;
    }

  2. 主流程模板

    int n = s.length();
    int maxLen = 0;

    for (int i = 0; i < n; i++) {
    int len1 = expand(s, i, i); // 奇数回文
    int len2 = expand(s, i, i + 1); // 偶数回文
    MaxLen = Math.max(maxLen, Math.max(len1, len2));
    }

Notice:

  1. while 条件顺序不能乱

正确顺序:先判边界,再比字符

while (left >= 0 && right < n && s.charAt(left) == s.charAt(right))

❌ 错误写法(可能越界):

s.charAt(left) == s.charAt(right) && left >= 0

  1. 注意空串 & 单字符

if (s == null || s.length() < 2) return s;

  1. 固定数据

回文子串的起始下标: start = i - (len - 1) / 2;

回文子串的结束下标: end = i + len / 2;

当前中心能扩散得到的「回文长度」: right - left - 1;

left– 和 right++ 是在“字符已经相等之后”执行的,也就是说:最后一次比较 是成功的,然后左右指针 又各自多走了一步,所以 最终得到的「回文长度」是 : right - left - 1

相关练习题

1. LeetCode 5. 最长回文子串

题意: 给你一个字符串 s,找到 s 中最长的回文子串。

2. LeetCode 680. 验证回文字符串 Ⅱ

题意: 给定一个非空字符串 s ,最多删除一个字符。判断是否能成为回文字符串。

3. LeetCode 132. 分割回文串 II

题意: 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文串。返回符合要求的 最少分割次数 。