最长回文子串

若一个字符串是回文串,那么它的首尾元素应该相同,并且若该字符串的长度大于2,除去首尾元素后依然是回文串。
由此可得到判断是否是回文串的递推公式,P ( i , j ) P(i, j)P(i,j) 代表子串S i S_{i}Si到S j S_{j}Sj是否是回文串:
P ( i , j ) = { true, 如果子串 S i … S j 是回文串 false, 其它情况 P(i, j)= \begin{cases}\text { true, } & \text { 如果子串 } S_{i} \ldots S_{j} \text { 是回文串 } \\ \text { false, } & \text { 其它情况 }\end{cases}P(i,j)={ true, false, 如果子串 Si…Sj 是回文串 其它情况
当且仅当S i + 1 S_{i+1}Si+1到S j − 1 S_{j-1}Sj−1是回文串,即P ( i + 1 , j − 1 ) = t r u e P(i+1, j-1) =trueP(i+1,j−1)=true,且S i = = S j S_{i}==S_{j}Si==Sj时,P ( i , j ) = t r u e P(i, j)=trueP(i,j)=true
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)
对于所有是回文串的子串,记录其长度,选择最长的
代码如下:
class Solution:
def longestPalindrome(self, s: str) -> str:
# 字符串长度小于2,则整个字符串都是回文串
n = len(s)
if n < 2:
return s
begin = 0
maxlen = 1 # 任意一个元素都是回文串
# 初始化,dp[i][j]表示s[i]...s[j]的子串是否是回文串
dp = [[False]*n for _ in range(n)]
for i in range(n):
dp[i][i] = True
# 任意一个元素s[i]都是回文串
# 递推,遍历所有开始结束位置i,j。并判断是否是回文串
for j in range(1,n):
for i in range(j):
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]
if dp[i][j] and j - i + 1 > maxlen:
# 记录最长的回文串索引
maxlen = j - i + 1
begin = i
return s[begin:begin+maxlen]
版权声明:本文为ltochange原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。