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
