最长回文子串
leetcode 5
若一个字符串是回文串,那么它的首尾元素应该相同,并且若该字符串的长度大于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) =true
P(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)=true
P(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:
n = len(s)
if n < 2:
return s
begin = 0
maxlen = 1
dp = [[False]*n for _ in range(n)]
for i in range(n):
dp[i][i] = True
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]
|