5. 最长回文子串
题目含义:给定一个字符串 s
,返回一个最长的回文子串,其中 s
是由小写字母和数字组成的,且 len(s)
至少为 1
。
如果字符串向前和向后读都相同,那么子串为回文串,比如 a
、aa
、aba
和 ababa
。
由此可以看出,单个字符是一个回文串;当子串的长度在 [2,3]
,例如 aa
和 aba
,只要判断第一个和最后一个字符是否一样;当子串的长度大于 3 时,例如 abba
,那么除了判断第一个和最后一个字符是否相等,还要判断 s[1] == s[len(s)-2]
。
因此,我们可以使用双指针和动态规划来做:dp[i][j]
表示在范围内 [i, j]
的子串是否是回文串,其中 i
和 j
是前后的两个索引/指针 ,且 i <= j
。
当 i == j
时,表示一个单个字符;
当 j - i >= 2
时,dp[is][j] = s[i] == s[j]
;
当 j - i >= 3
时,dp[is][j] = s[i] == s[j] and dp[i+1][j-1]
。
class Solution:def longestPalindrome(self, s: str) -> str:n = len(s)ans = s[0:1] # 字串长度至少为 1dp = [[False] * n for _ in range(n)] for i in range(n-2, -1, -1):for j in range(i+1, n):if i == j: dp[i][j] = True # i 和 j 指向同一个字符elif j-i <= 2:dp[i][j] = s[i] == s[j]else:dp[i][j] = (s[i] == s[j]) and dp[i+1][j-1]if dp[i][j] and j-i+1 > len(ans):ans = s[i: j+1] # 左闭右开return ans