上次写的代码简直没法看。
第一个思路答案上叫中心扩散法:
就是以一个字母为轴进行左右的比较,如果相同继续比较,如果不同,停止比较轴往前进一个。另外考虑到回文子串可为双数可为单数,那么考虑用0.5为轴的步长
class Solution(object):
def longestPalindrome(self, s):
if len(s)<=1:
return s
else:
s_r=s[0:1]
length_r = length_cur = 1
for i in range(1,2*len(s)-2):#比如s长度等于6的时候,轴从0.5到4.5(第9个0.5)
left_point = int(i*0.5-0.5)
right_point = int(i*0.5+1)
while left_point != -1 and right_point != len(s):
if s[left_point]==s[right_point]:
left_point += -1/2
right_point = int (right_point+1)
else:
break
length_cur = right_point - left_point-1
if length_cur>length_r:
length_r=length_cur
s_r=s[left_point+1:right_point]
return s_r
第二个思路动态规划法:
观察这道题其实如果按照普通的暴力列举法的话需要判断个子串
即:
s[0:0]~s[0:n]、
s[1:1]~s[1:n]、
...
s[n:n]、
其中有些串的判断是关联的,比如判断s[1:4]是否是回文,充要条件是s[2:3]满足回文,且s[1]==s[4]。
即可以写出状态转移方程:
P(i,j)=P(i+1,j-1)s[i]==s[j]
所以P(i,j)需要依赖P(i+1,j-1),那就可以构造二维列表dp[][]用来记录,上代码
class Solution:
def longestPalindrome(self, s):
n=len(s)
length_r=1
index_head=0
dp=[[False]*n for p in range(n)]#初始化dp表
for i in range(n):
dp[i][i]=True#初始化对角线
for i in range(1,n):#列标,[1,n)
for j in range(i):#行标[0,i),不能碰到对角线
if i-j == 1:
if s[i] == s[j]:
dp[i][j] = True
if i-j+1>length_r:
length_r=i-j+1
index_head=j
else:
if dp[i-1][j+1] == True and s[i] == s[j]:
dp[i][j] = True
if i-j+1>length_r:
length_r=i-j+1
index_head=j
return s[index_head:index_head+length_r]