📜  Manacher算法-线性时间最长回文子串-第1部分(1)

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

Manacher算法-线性时间最长回文子串-第1部分

回文子串指的是正反读都一样的字符串,如“level”,“noon”等。在字符串处理中,寻找最长回文子串是一个经典问题,也是一个非常有趣的问题。本文将介绍Manacher算法,该算法可以在线性时间内求解最长回文子串。

算法思路

Manacher算法是一种基于对称性的思想,该算法在处理每个字符时,先找到以当前字符为对称中心的最长回文子串半径,然后继续向后遍历字符串。通过维护一个“右边界”和“对称中心”两个变量,可以以线性时间复杂度完成遍历。

算法流程

设字符串为s,s长度为n,回文子串的长度为len,对称中心为mid。算法具体流程如下:

  1. 构造新字符串t:在s中每个字符之间添加特殊字符“#”,并在s的开头和结尾添加字符“$”和“%”,用于避免越界。例如,字符串s=“ABB”转换为字符串t=“$#A#B#B#%”。

  2. 初始化数组P:P[i]代表以t[i]为对称中心的最长回文子串的半径长度。

  3. 初始化变量mid和right:mid表示已经求得的最长回文子串的对称中心,right表示mid对应的最长回文子串的右边界。

  4. 遍历字符串t:从左到右遍历t数组,对于每个字符t[i],先判断i是否在已经求得的最长回文子串的右边界之内。如果i在最长回文子串的右边界之内,则将P[i]的初值设为P[mid-(i-mid)](即t[i]关于mid的对称位置的回文半径),同时扩展P[i]的范围(向左右两边扩展),直至不能扩展为止。如果i在最长回文子串的右边界之外,就以t[i]为中心,向外扩展找最长回文子串,并更新mid和right的值。

  5. 遍历P:在P数组中找到最大值,其即为最长回文子串的长度。

  6. 通过最长回文子串的长度和对称中心mid,可以求得最长回文子串在s中的位置和具体内容。

代码实现

下面是Python语言实现Manacher算法的代码片段(以字符串s=“babad”为例):

# 构造新字符串t
t = '$#' + '#'.join(list(s)) + '#%'
n = len(t)

# 初始化数组P
P = [0] * n

# 初始化中心点和右边界
mid, right = 0, 0

for i in range(1, n-1):
    if i < right:
        P[i] = min(P[mid-(i-mid)], right-i)
    
    while t[i-P[i]-1] == t[i+P[i]+1]:
        P[i] += 1
    
    if i + P[i] > right:
        mid, right = i, i + P[i]

# 找到最长回文子串的长度
max_len, max_mid = max((P[i], i) for i in range(1, n-1))

# 求得最长回文子串
start = (max_mid - max_len) // 2
end = start + max_len - 1
longest_palindrome = s[start:end+1]
总结

Manacher算法通过对称性的思想,以线性时间复杂度解决了最长回文子串的求解问题,是字符串处理中非常经典和有趣的问题。掌握了Manacher算法,可以为字符串处理类问题提供有效的思路和解决方法。