class Solution:
def longestPalindrome(self, A: str) -> str:
# 首位填其他字符,是的回文串始终是奇数,不用考虑偶数情况
n=len(A)
s="#"+"#".join(list(A))+"#"
# 使用臂长代表回文串半径,初始值为1,臂长-1就是所求回文串长度
n=2*n+1
arms=[1]*n
# 记录包含最右边的回文串中间值及其最右边的索引
# 因为遍历过最右的索引不会再被遍历,所以复杂度为O(n)
max_mid,max_ind=-1,-1
ans=0
res=(0,0)
for i in range(n):
# 更新逻辑是,与max_mid对称位置的臂长加上i仍然够不到最右索引,这里是不包含的,包含就说明够到了,则当前臂长直接等于对称点臂长,否则为i够到最右索引处的长度,然后在进行扩展。
if arms[2*max_mid-i]+i<max_ind:
arms[i]=arms[2*max_mid-i]
else:
arms[i]=max_ind-i+1
# 这里同扩展方法
l,r=i-arms[i],i+arms[i]
while l>=0 and r<n and s[l]==s[r]:
l-=1
r+=1
arms[i]+=1
if arms[i]>ans:
ans=arms[i]-1
res=(l+1,r-1)
max_mid=i
max_ind=r-1
return s[res[0]:res[1]+1].replace("#","")
(1)首先是将奇偶两种情况转成一种情况,用到了类似于奇数+偶数=奇数的思想。
(2)很多,包括动态规划首先需要思考的就是从最右结果开始,后面的结果如何从前面推导出来。这里维护了最右索引和对应的中心点。如果每次i即便加上对称点臂长也无法够到最大索引,明显它也无法够到,更新臂长即可。如果够得到就需要重新扩展了,然后更新臂长,最右索引及其对应中心点。