📜  最长回文子串|套装1(1)

📅  最后修改于: 2023-12-03 15:10:37.498000             🧑  作者: Mango

最长回文子串 | 套装1

简介

回文串指一个字符串正着读和倒着读是一样的,最长回文子串指在一个字符串中,找到一个最长的回文子串。例如,在字符串 "racecar" 中,最长的回文子串是 "racecar"。

解法1:暴力破解法

暴力破解法是寻找所有可能的子串,判断其是否为回文串,时间复杂度为O(n^3)。

代码示例:

def longest_palindrome(s: str) -> str:
    n = len(s)
    ans = ""
    for i in range(n):
        for j in range(i, n):
            if s[i:j+1] == s[i:j+1][::-1]:
                if len(s[i:j+1]) > len(ans):
                    ans = s[i:j+1]
    return ans
解法2:中心扩展法

中心扩展法通过枚举所有可能的回文中心位置,然后向两端扩展,时间复杂度为O(n^2)。

代码示例:

def longest_palindrome(s: str) -> str:
    n = len(s)
    ans = ""
    for i in range(n):
        # 寻找以i为中心的回文串
        left, right = i, i
        while left >= 0 and right < n and s[left] == s[right]:
            left -= 1
            right += 1
        if right - left - 1 > len(ans):
            ans = s[left+1:right]
        # 寻找以i和i+1为中心的回文串
        left, right = i, i+1
        while left >= 0 and right < n and s[left] == s[right]:
            left -= 1
            right += 1
        if right - left - 1 > len(ans):
            ans = s[left+1:right]
    return ans
解法3:马拉车算法

马拉车算法(Manacher's Algorithm)是O(n)的算法,通过利用回文串的对称性,快速找到以每个位置为中心的回文子串,从而求出整个最长回文子串。

代码示例:

def longest_palindrome(s: str) -> str:
    t = "^#" + "#".join(s) + "#$"
    n = len(t)
    p = [0] * n
    center = right = 0
    for i in range(1, n-1):
        if i < right:
            p[i] = min(right - i, p[2*center - i])
        while t[i+p[i]+1] == t[i-p[i]-1]:
            p[i] += 1
        if i + p[i] > right:
            center, right = i, i + p[i]
    max_len, idx = max((v, i) for i, v in enumerate(p))
    return s[(idx - max_len)//2 : (idx - max_len)//2 + max_len]
总结

暴力破解法虽然简单易懂,但是在实际应用中效率较低。中心扩展法能够较快地找到最长回文子串,但是需要考虑回文串长度奇偶性的问题。马拉车算法是目前最优解,时间复杂度为O(n),但是实现起来较为复杂,需要仔细考虑各种细节问题。