跳转至

5. 最长回文子串

题目

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

示例 1:

输入: s = "babad"

输出: "bab"

示例 2:

输入: s = "cbbd"

输出: "bb"

题解

Go
func longestPalindrome(s string) string {
    res := ""
    for i := 0; i < len(s); i++ {
        res = maxPalidrome(s, i, i, res)
        res = maxPalidrome(s, i, i+1, res)
    }
    return res
}

func maxPalidrome(s string, i, j int, res string) string {
    sub := ""
    for i >= 0 && j < len(s) && s[i] == s[j] {
        sub = s[i:j+1]
        i--
        j++
    }

    if len(res) < len(sub) {
        res = sub
    }
    return res
}
Python
class Solution:
    def longestPalindrome(self, s: str) -> str:
        """
        从[left, right]为中心向两端扩展,找到最长回文串,并返回最大长度
        """
        def expand_search_longest(left: int, right: int):
            n = len(s)
            while left >= 0 and right < n and s[left] == s[right]:
                left -= 1
                right += 1
            # 退出循环时,right和left一定是指向不是回文串的部分,即回文串为[left + 1, right - 1]
            return right - left - 1

        n = len(s)
        length = 1 # 最长回文子串的长度
        start = 0  # 最长回文子串的起始位置
        for i in range(n):
            # 枚举每个i为中心扩展
            odd_len = expand_search_longest(i, i)      # 以i为中心扩展,得到奇数长度的回文串  
            even_len = expand_search_longest(i, i+1)   # 以[i, i+1]为中心扩展,得到偶数长度的回文串  
            local_max = max(odd_len, even_len)    # 以i为中心扩展的最大长度
            if local_max > length:
                length = local_max
                start = i - (local_max - 1) // 2     # 根据中心点和长度计算起始点

        return s[start: start + length] # 截取最长回文子串

复杂度

  • 时间复杂度: \(O(n^2)\),其中 \(n\) 是字符串的长度。长度为 1 和 2 的回文中心分别有 \(n\)\(n−1\) 个,每个回文中心最多会向外扩展 \(O(n)\) 次。
  • 空间复杂度: \(O(1)\)

参考