5分钟掌握Manacher算法:从暴力匹配到高效回文检测
回文串检测是算法竞赛和面试中的经典问题,但很多人在面对这个问题时,第一反应往往是暴力匹配法。这种方法的直观性确实让人容易理解,但当字符串长度达到10^5级别时,O(n²)的时间复杂度会让程序变得异常缓慢。今天我们要介绍的Manacher算法(又称马拉车算法),能在O(n)时间内解决这个问题,而且代码实现出奇地简洁。
1. 为什么需要Manacher算法?
假设给你一个字符串"abacabacabb",要求找出其中最长的回文子串。最直接的方法是枚举所有可能的子串并检查是否为回文:
python复制def is_palindrome(s):
return s == s[::-1]
def longest_palindrome_naive(s):
max_len = 0
result = ""
for i in range(len(s)):
for j in range(i, len(s)):
substring = s[i:j+1]
if is_palindrome(substring) and len(substring) > max_len:
max_len = len(substring)
result = substring
return result
这种方法虽然正确,但时间复杂度高达O(n³)。稍微优化一下,使用中心扩展法可以将复杂度降到O(n²):
python复制def expand_around_center(s, left, right):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return right - left - 1
def longest_palindrome_center(s):
start = end = 0
for i in range(len(s)):
len1 = expand_around_center(s, i, i) # 奇数长度
len2 = expand_around_center(s, i, i+1) # 偶数长度
max_len = max(len1, len2)
if max_len > end - start:
start = i - (max_len - 1) // 2
end = i + max_len // 2
return s
