题目
给你一个字符串 s,找到 s 中最长的回文子串。
示例
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
解法一
动态规划的方式
将状态DP[i][j]设为字串s[i:j]是否为回文子串
则状态转移方程可以定为DP[i][j]=DP[i+1][j-1]∧s[i]==s[j]
边缘条件DP[i][i]=True,DP[i][i+1]=s[i]==s[i+1]
max_length一开始设定为1,因为最长字串可以是一个字母
class Solution:
def longestPalindrome(self, s: str) -> str:
begin=0
maxlength=1
s_length=len(s)
if s_length<2:
return s
dp=[[False]*s_length for _ in range(s_length)]
for i in range(s_length):
dp[i][i]=True
for L in range(2,s_length+1):
for i in range(s_length-1):
j = i + L -1
if j >= s_length:
break
if s[i]!=s[j]:
dp[i][j]=False
else:
if L<=3:
dp[i][j]=True
else:
dp[i][j]=dp[i+1][j-1]
if dp[i][j]==True and L > maxlength:
maxlength=L
begin=i
return s[begin:begin+maxlength]
解法二
中心扩散法
有两种情况,一种是从一个开始扩散,一种是从两个开始扩散。
class Solution:
def fromcenter(self,s,left,right):
while left>=0 and right<len(s) and s[left]==s[right]:
left-=1
right+=1
return left+1,right-1
def longestPalindrome(self, s: str) -> str:
left1=right1=0
left2=right2=0
maxlength=1
begin=0
for i in range(len(s)):
left1,right1=self.fromcenter(s,i,i)
left2,right2=self.fromcenter(s,i,i+1)
if right1-left1+1>maxlength:
maxlength=right1-left1+1
begin=left1
if right2-left2+1>maxlength:
maxlength=right2-left2+1
begin=left2
return s[begin:maxlength+begin]