题目
分析
看到这道题,一开始想用寻找0开头的最长回文子串的方式做。但是在最后一个case的时候超时了。
那么换一种思路来看。
在kmp中next数组构成存储在i位置的最长公共前后缀的长度。
我们把 acbb 翻转成bbca。acbb的前缀和bbca的后缀的最大公共长度的串是“a”。
next[-1]表示当遍历完bbca时的最大公共前后缀的长度L,正式我们需要的值。
返回时把acbb L后面的串翻转之后放在前面就可以了。
python代码
class Solution(object):
def shortestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
# start = -1
# max_len = 1
# n = len(s)
# dp = [[False]*n for i in range(n)]
# for i in range(n):
# dp[i][i] = True
# for i in range(1,n):
# for j in range(0,i):
# if s[i]!=s[j]:
# dp[j][i] = False
# else:
# if i-j<3:
# dp[j][i]=True
# else:
# dp[j][i] = dp[j+1][i-1]
# if dp[j][i]:
# if i-j+1>max_len and j==0:
# start = j
# max_len = max(max_len,i-j+1)
# if max_len>1 and start==0:
# return s[max_len:][::-1]+s
# else:
# return s[1:][::-1]+s
if len(s)<=1: return s
s1 = s[::-1]
if s==s1: return s
i = 1
j = 0
next_arr = [0]* len(s)
while i<len(s1) and j<len(s):
if s1[i]==s[j]:
next_arr[i] = j+1
j+=1
i+=1
elif j!=0:
j = next_arr[j-1]
else:
next_arr[i]=0
i+=1
max_len = next_arr[-1]
return s[max_len:][::-1] +s