class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n == 0:
return ''
string = '#' + '#'.join(list(s)) + '#'
n = len(string)
p = []
center, right = -1, -1
mcenter, mrad = -1, -1
for i in range(n):
cur = 0
mirror = 2 * center - right
if i < right and mirror >= 0: # 当前位置已经超出了最右的位置, 需要重新以当前位置为中心, 向外搜索
cur = min(right - i, p[mirror])
while i - cur - 1 >= 0 and i + cur + 1 < n and string[i - cur - 1] == string[i + cur + 1]:
cur += 1
if i + cur > right:
right = i + cur
center = i
if cur > mrad:
mcenter = i
mrad = cur
p.append(cur)
return string[mcenter - mrad: mcenter + mrad].replace('#', '')
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n == 0:
return ''
p = [False] * n
cur_start, cur_length = 0, 1
for i in range(n - 1, -1, -1):
for j in range(n - 1, i - 1, -1):
t = False
if j - i > 1 and p[j - 1] and s[i] == s[j]:
t = True
elif j - i == 1 and s[i] == s[j]:
t = True
elif j == i:
t = True
elif j < i:
break
p[j] = t
if t and (j - i + 1) > cur_length:
cur_start = i
cur_length = j - i + 1
return s[cur_start: cur_start + cur_length]
Manacher Algorithm
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n == 0:
return ''
string = '#' + '#'.join(list(s)) + '#'
n = len(string)
p = []
center, right = -1, -1
for i in range(n):
cur = 0
mirror = 2 * center - right
if i < right and mirror >= 0: # 当前位置已经超出了最右的位置, 需要重新以当前位置为中心, 向外搜索
cur = min(right - i, p[mirror])
while i - cur - 1 >= 0 and i + cur + 1 < n and string[i - cur - 1] == string[i + cur + 1]:
cur += 1
if i + cur > right:
right = i + cur
center = i
p.append(cur)
center, rad = max([(i, t) for i, t in enumerate(p)], key=lambda x: x[1])
return string[center - rad: center + rad].replace('#', '')