LeetCode刷题笔记:5. 最长回文子串

83 阅读2分钟

题目描述

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

示例 1:

输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。

示例 2:

输入: s = "cbbd"
输出: "bb"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成

解题思路

采用中心扩展算法,从字符串str中的字符str[i]开始,使用两个指针left、right同时分别向左、右移动,直到str[left] != str[right]为止,记录下回文子串的长度len,进行下一轮对i的遍历,最后返回len最大的回文子串。

特别需要注意的是,由于回文子串len的长度位置,因此需要根据两种可能性进行查找:对于len为奇数的情况,起始时left == right;而对于len为偶数的情况,起始时right == left + 1。

最终代码

public String longestPalindrome(String s) {
    // 排除字符串为空或长度小于2的情况
    if (s == null || s.length() < 2) return s;
    // 初始化最长回文子串的起始位置和长度
    int resIdx = 0, resLen = 1;
    // 遍历字符串,每一轮的i为中心位置
    for (int i = 0; i < s.length() - 1; i++){
        // 假设回文子串为奇数的情况
        int len1 = longestLen(s, i, i);
        // 假设回文子串为偶数的情况
        int len2 = longestLen(s, i, i+1);
        // 更新最长回文子串长度以及起始位置
        if (len1 > resLen) {
            resLen = len1;
            resIdx = i - resLen / 2;
        }
        if (len2 > resLen) {
            resLen = len2;
            resIdx = i - (resLen / 2 - 1);
        }
    }
    return s.substring(resIdx, resIdx + resLen);
}
// 根据提供的初始指针left、right查找最长回文子串长度
private int longestLen(String str, int left, int right){
    // 从提供的初始指针left、right开始由中心向左右移动,直到两字符不相等
    while (left >= 0 && right < str.length() && str.charAt(left) == str.charAt(right)){
        left--;
        right++;
    }
    return right - left - 1;
}