给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
动态规划
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
if not s or len(s) == 1: return s
def func(s, start, end):
return s[start:end]
out = ''
maxlen = 0
for i in range(len(s)):
if i + maxlen // 2 > len(s): break
start = i
end = start + 1
if end < len(s) and s[start] == s[end]:
_end = end + 1
_start = start
_sub = s[_start:_end]
while _start > 0 and _end < len(s) and s[_start - 1] == s[_end]:
_start -= 1
_end += 1
_sub = func(s, _start, _end)
if len(_sub) > maxlen:
maxlen = len(_sub)
out = _sub
sub = s[start:end]
while start > 0 and end < len(s) and s[start - 1] == s[end]:
start -= 1
end += 1
sub = func(s, start, end)
if len(sub) > maxlen:
maxlen = len(sub)
out = sub
return out
结果?????打扰了,代码也还有冗余的地方,还待优化
优化后(因为进行了偶数对称的预处理,所以时间长了一下,但是代码简洁一些【强迫症】)
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
if not s or len(s) == 1: return s
#preprocess
data = '#'
for i in range(len(s)):
data += s[i] + '#'
data += '#'
out = ''
maxlen = 0
for i in range(len(data)):
if i + maxlen // 2 > len(data): break
start = i
end = start + 1
sub = data[start:end]
while start > 0 and end < len(data) and data[start - 1] == data[end]:
start -= 1
end += 1
sub = data[start:end]
if len(sub) > maxlen:
maxlen = len(sub)
out = sub
res = ''
for i in range(len(out)):
if out[i] != '#': res += out[i]
return res
据说最好的马拉车
我是看这个博客的思路写的,大概是长这样
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
if not s or len(s) == 1: return s
#preprocess
data = '#'
for i in range(len(s)):
data += s[i] + '#'
print(data)
def cal(string, center, le):
length = le
while (center-length-1) >= 0 and (center+length+1) < len(string) and string[center-length-1] == string[center+length+1]:
length += 1
return length
iCenter = 0
length = []
length.append(cal(data, 0, 0))
sub_left = iCenter - length[iCenter]
sub_right = iCenter + length[iCenter]
sub = data[0]
for i in range(1, len(data)):
length.append(0)
_len = length[iCenter]
iRight = iCenter + _len
print('right', iRight, iCenter)
if i < iRight - length[i]: #有镜像点时
length[i] = min(iRight - i, length[2*iCenter - i]) #看看左边有没有溢出
#print('1', length, i, sub)
if i >= iRight - length[i]: 无镜像点时,或者左边溢出之后可能以i为中心能有更长的子串
length[i] = cal(data, i, length[i])
#print('2', length, i, sub)
if length[i] > length[iCenter]:#比较一下长度
iCenter = i
sub_left = iCenter - length[iCenter]
sub_right = iCenter + length[iCenter]
sub = data[sub_left:sub_right+1]
#print('3', length, i, sub, sub_left, sub_right)
return sub[1::2]
调了很久 快了很多