1 问题
给你一个字符串 s
,找到 s
中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
2 答案
这题直接不会
2.1 动态规划法
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2: # 如果长度小于2,直接返回
return s
max_len = 1
begin = 0
dp = [[False] * n for _ in range(n)]
for i in range(n):
dp[i][i] = True # 每个单独的字母都是一个回文子串
for L in range(2, n + 1):
for i in range(n):
j = L + i - 1
if j >= n:
break
if s[i] != s[j]:
dp[i][j] = False
else:
if j - i < 3: # 如果两个相同是回文子串
dp[i][j] = True
else:
dp[i][j] = dp[i + 1][j - 1] # 为了应对 aaaa 这样的长子串
if dp[i][j] and j - i + 1 > max_len:
max_len = j - i + 1
begin = i
return s[begin:begin + max_len]
这样写应该也是对的
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2:
return s
max_length = 1
begin = 0
dp = [[False]*n for _ in range(n)] # 动态规划列表
for i in range(n):
dp[i][i] = True
for L in range(2, n+1):
for i in range(n):
j = L + i - 1 # L 子串大小
if j >= n:
break
if s[i] != s[j]:
pass # 与原版相比,改成了pass,因为一般默认为False,所以不用重新赋值为False
else:
if L < 3:
dp[i][j] = True
else:
dp[i][j] = dp[i+1][j-1]
if dp[i][j] == True and max_length < L:
max_length = L
begin = i
return s[begin: begin+max_length]
不能这样把for i in range(n):
放到for L in range(2, n + 1):
前面,因为这时dp[i + 1][j - 1]
还没有更新,还是False
,对于aaaa
这样的字符串会报错
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2:
return s
dp = [[False] * n for _ in range(n)]
max_len = 1
begin = 0
for j in range(n):
dp[j][j] = True
for i in range(n):
for L in range(2, n + 1):
j = i + L - 1
if j >= n:
break
if s[i] != s[j]:
dp[i][j] = False
else:
if L == 2:
dp[i][j] = True
else:
dp[i][j] = dp[i + 1][j - 1]
if dp[i][j] and L > max_len:
begin = i
max_len = L
print(begin)
print(max_len)
return s[begin: begin + max_len]
3 知识点
在本题中,动态规划的状态转移方程为:
P ( i , j ) = P ( i + 1 , j − 1 ) ∧ ( S i = = S j ) P(i, j)=P(i+1, j-1) \wedge\left(S_i==S_j\right) P(i,j)=P(i+1,j−1)∧(Si==Sj)