主要对马拉车算法来一波意识流理解,方便不手撕算法的时候可以嘴嗨一波
1.有点像滑窗法。滑窗的中心作为一个重要迭代遍历center,滑窗的右边界是另一个重要迭代参数maxright,和中心一起更新。
2.遍历整个字符串,假设正在遍历的字符索引为i:
2.1.如果i大于maxright,按照一般的中心扩展算法开始算
2.2.如果i<maxright.则i 关于 center 有一个镜像点 mirror.对于P[mirror]分三种情况进行讨论.(注:P的对应位置存储对应字符为中心的最大回文长度)
1)如果maxright-i>P[mirror],那么P[i]=P[mirror]
2)如果
maxright-i=P[mirror],先给P[i]赋值P[mirror],由于maxright右边的都没有探索过,这个时候再基于P[i]进行探索
3)如果
maxright-i<P[mirror],直接给P[i]赋值maxrigth-i。因为由mirror和center的回文性质可以推出maxright+1和i-(maxright-i)-1对应的元素肯定不相等。
贴上leetcode 5.最长回文子串马拉车算法的代码
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
if len(s)<2:
return str(s)
s1 = list(s)
s = ['#']
for i in s1:
s.append(i)
s.append('#')
center = 0
maxright = 0
p = [0 for _ in range(len(s))]
for i in range(len(s)):
if i <maxright:
mirror = 2*center-i
p[i] = min(p[mirror],maxright-i)
temp = p[i]
temp+=1
while i -temp>-1 and i+temp<len(s) and s[i-temp]==s[i+temp]:
temp+=1
p[i]+=1
if i+p[i]>maxright:
maxright = i+p[i]
center = i
ans_center = p.index(max(p))
ans_temp = s[ans_center-max(p):ans_center+max(p)+1]
ans = ''
for i in ans_temp:
if i !='#':
ans+=i
return ans