5. 最长回文子串

108 阅读2分钟

题目

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

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

  示例 1:

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

示例 2:

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

提示:

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

解题思路:

使用 Manacher 算法,这是一种特别为回文子串设计的线性时间复杂度算法。它通过构造一个新的字符串,在原有字符间插入特殊字符(如#),并在新字符串上执行回文搜索。算法利用已知的回文信息来避免重复计算,从而极大提高效率。

代码

class Solution:
    def longestPalindrome(self, s: str) -> str:
        # Transform S into T.
        # For example, S = "abba", T = "^#a#b#b#a#$".
        # ^ and $ signs are sentinels appended to each end to avoid bounds checking
        T = '#'.join(f"^{s}$")
        n = len(T)
        P = [0] * n
        C = R = 0
        
        for i in range(1, n-1):
            P[i] = (R > i) and min(R - i, P[2*C - i])  # equals to i' = C - (i-C)
            
            # Attempt to expand palindrome centered at i
            while T[i + 1 + P[i]] == T[i - 1 - P[i]]:
                P[i] += 1

            # If palindrome centered at i expand past R, adjust center based on expanded palindrome.
            if i + P[i] > R:
                C, R = i, i + P[i]

        # Find the maximum element in P.
        maxLen, centerIndex = max((n, i) for i, n in enumerate(P))
        start = (centerIndex - maxLen) // 2  # start from the beginning of the palindrome
        return s[start: start + maxLen]

运行:

python
solution = Solution() 
print(solution.longestPalindrome("babad"))  # 可能输出: "bab""aba"
print(solution.longestPalindrome("cbbd"))  # 输出: "bb"

总结:

Manacher 算法是解决最长回文子串问题的理想选择,尤其是在处理大型数据集时。它避免了不必要的重复计算,保证了算法的时间复杂度严格为 O(n),使得在实际应用中能够快速找到最长回文子串。

题目链接

leetcode.cn/problems/lo…