题目
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
示例 2:
输入: s = "cbbd"
输出: "bb"
提示:
1 <= s.length <= 1000s仅由数字和英文字母组成
解题思路:
使用 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),使得在实际应用中能够快速找到最长回文子串。