- 动态规划
class Solution:
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
if not s:
return s
count = 1
tmp = s[0]
nums = len(s)
mark = [[0 for _ in range(nums)] for _ in range(nums)]
for ii in range(nums):
mark[ii][ii] = 1
for i in range(2, nums+1):
for j in range(nums-i+1):
if i==2:
if s[j] == s[j + i -1]:
mark[j][i+j-1] = 1
if i > count:
tmp = s[j:j+i]
else:
if s[j] == s[j + i -1] and mark[j+1][i+j-2]:
mark[j][i+j-1] = 1
if i > count:
tmp = s[j:j+i]
else:
mark[j][i+j-1] = 0
return tmp
- manacher
class Solution:
def longestPalindrome(self, s):
if len(s) <= 1:
return s
mark = ['^', '#']
for ele in s:
mark.extend([ele, '#'])
mark.append('$')
table = [0] * len(mark)
c = r = 0
tmp = 0
reuslt = []
for i in range(1, len(table) - 1):
# 这个地方得注意,i的mirror的左侧边界得大于c的左侧边界,不能小于或等于
if i < r:
table[i] = min(table[2*c - i], r - i)
while mark[i - table[i] - 1 ] == mark[i + table[i] + 1 ]:
table[i] += 1
if table[i] > tmp:
result = mark[i - table[i] : i + table[i] + 1]
tmp = table[i]
if i + table[i] > r:
c = i
r = i + table[i]
return ''.join([ele for ele in result if ele != '#'])
感觉网上讲的manacher方法都有点省略。
整个判断应该如下,上面方法只不过是对下面的整理。
if i < r:
if table[2*c - i] < r - i:
table[i] = table[2*c - i]
elif table[2*c - i] > r - i:
table[i] = r - i
else:
table[i] = r - i
while mark[i - table[i] - 1] == mark[i + table[i] + 1]:
table[i] += 1
else:
while mark[i - table[i] - 1] == mark[i + table[i] + 1]:
table[i] += 1
- 中心向两边扩散(感觉实现的有点累赘)
def broadcast(s):
if len(s) <= 1:
return s
res = ''
for i in range(len(s)-1):
res1 = func(s, i, i)
res2 = func(s, i, i+1)
tmp = res1 if len(res1) > len(res2) else res2
res = res if len(res) >= len(tmp) else tmp
return res
def func(s, i, j):
res = s[i] if i==j else s[i] + s[j]
i -= 1
j += 1
while i >= 0 and j <= len(s)-1:
if s[i] == s[j]:
res = s[i] + res + s[j]
i-=1
j+=1
else:
break
return res