返回

LeetCode最长回文子串:算法练习系列,迎接复杂挑战!

前端

导语

欢迎来到算法练习系列的第五天!今天,我们将踏上LeetCode最长回文子串的征程,这是一道难度较高的算法题,但只要充分考虑各种情况,你就能避免不断踩坑。

问题陈述

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

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是回文串,但 "bab" 更长。

示例 2:

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

示例 3:

输入:s = "a"
输出:"a"

示例 4:

输入:s = "ac"
输出:"a"

算法讲解

解决最长回文子串问题,有以下三种算法:

  1. 中心扩展算法 :从字符串的中心开始向两侧扩展,直到找到最长的回文子串。
  2. 马拉车算法 :预处理字符串,然后使用动态规划来计算最长回文子串。
  3. KMP算法 :将字符串转换为一个新的字符串,然后使用KMP算法来找到最长的回文子串。

算法实现

中心扩展算法

def longest_palindrome(s):
    def expand_around_center(left, right):
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1
            right += 1
        return s[left + 1:right]

    longest = ""
    for i in range(len(s)):
        # 以单个字符为中心扩展
        palindrome1 = expand_around_center(i, i)
        # 以相邻两个字符为中心扩展
        palindrome2 = expand_around_center(i, i + 1)
        longest = max(longest, palindrome1, palindrome2, key=len)
    return longest

马拉车算法

def longest_palindrome(s):
    n = len(s)
    dp = [[False] * n for _ in range(n)]

    # 初始化单个字符为回文子串
    for i in range(n):
        dp[i][i] = True

    # 长度为2的回文子串
    for i in range(n - 1):
        if s[i] == s[i + 1]:
            dp[i][i + 1] = True

    # 长度大于2的回文子串
    max_length = 1
    start = 0
    for k in range(3, n + 1):
        for i in range(n - k + 1):
            j = i + k - 1
            if s[i] == s[j] and dp[i + 1][j - 1]:
                dp[i][j] = True
                if k > max_length:
                    max_length = k
                    start = i

    return s[start:start + max_length]

KMP算法

def longest_palindrome(s):
    # 预处理字符串
    new_s = "#" + "#".join(s) + "#"

    # 计算最长公共前缀
    n = len(new_s)
    p = [0] * n
    for i in range(1, n):
        j = p[i - 1]
        while j > 0 and new_s[i] != new_s[j]:
            j = p[j - 1]
        if new_s[i] == new_s[j]:
            j += 1
        p[i] = j

    # 找到最长的回文子串
    max_length = 0
    start = 0
    for i in range(1, n):
        if p[i] > max_length:
            max_length = p[i]
            start = (i - max_length) // 2

    return s[start:start + max_length]

总结

最长回文子串问题是算法练习中的经典问题,它有中心扩展算法、马拉车算法和KMP算法三种解法。掌握这些算法,你将成为算法练习中的高手!