class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n == 0:
return ''
max_len = 1
left = right = 0
for i in range(n):
len1 = self.center_search(i, i, s)
len2 = self.center_search(i, i + 1, s)
len3 = max(len1, len2)
if len3 > max_len:
left = i - (len3 - 1) // 2
right = i + len3 // 2
max_len = len3
return s[left: right + 1]
def center_search(self, i, j, s):
while i >= 0 and j < len(s) and s[i] == s[j]:
i -= 1
j += 1
return j - i - 1
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 - i
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('#', '')