题目解读:
这是一道寻找最长回文子串的题,怎么去寻找最长回文子串是一个问题,直接暴力求解,遍历所有可能的首字母的位置以及尾字母的位置,但是时间复杂度为O(n^2)。
因此我们就需要用一个时间复杂度上要好的算法,也就是manacher算法,俗称“马拉车算法”。
马拉车算法到底是怎么回事呢?
其实要理解马拉车算法不难,主要就是有效的利用到了对称的信息来解决问题,只需要做一次遍历就可以解决问题,时间复杂度为O(n),具体可以自行百度malacher算法,然后理解的时候,就看看这个算法到底是怎么利用对称信息直接做判断,而不是从中心向两边做循环去判断到底有多长的回文。(这里就不解释什么是manacher算法了)
具体代码如下:
class Solution:
def longestPalindrome(self, s: str) -> str:
'''
manacher algorithm
note:
keep a R to be the right bound
keep a C to be a center of the R
'''
new_str = '#'
for char in s:
new_str += char + '#'
# print(new_str)
#init
R = 0
C = 0
CL = 0
radius = [1]
#first get a R and C
#then iterate it
for p in range(1, len(new_str)):
#p > R, iterate the C and R
if p >= R:
C = p
backward = forward = p
while backward - 1 >= 0 and forward + 1 < len(new_str):
if new_str[backward - 1] == new_str[forward + 1]:
backward = backward - 1
forward = forward + 1
else:
break
CL = backward
R = forward
radius.append(R - C + 1)
elif p < R:
#find p2
p2 = 2*C - p
p2L = p2 - radius[p2] + 1
if p2L < CL:
radius.append(R - p + 1)
if p2L > CL:
radius.append(radius[p2])
if p2L == CL:
forward = R
backward = p - (R - p)
while backward - 1 >= 0 and forward + 1 < len(new_str):
if new_str[forward + 1] == new_str[backward - 1]:
forward = forward + 1
backward = backward - 1
else:
break
C = p
R = forward
CL = backward
radius.append(R - C + 1)
max_radiu = max(radius)
c = radius.index(max_radiu)
left = c - max_radiu + 1
right = c + max_radiu
res = new_str[left : right]
res = res.replace('#', '')
return res
# tmp = Solution()
# print(tmp.longestPalindrome('abacab'))
提交结果如下: