5. 最长回文子串

5. 最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

示例 2:
输入: “cbbd”
输出: “bb”

动态规划(DP)

我们观察一个回文子串“adbcbda”,则“dbcbd”,“bcb”,也是回文子串,同理,如果"bcb"是回文子串,则“dbcbd”和“adbcbda”也一定是回文子串。
所以这个问题可以转化为,如果区间 [ i , j ] [i,j] [i,j]确定为回文子串,则判断区间 [ i − 1 , j + 1 ] [i-1,j+1] [i1,j+1]是否是回文子串,这个思路和分治法不同在于,是否进行判断区间 [ i − 1 , j + 1 ] [i-1,j+1] [i1,j+1]依赖与区间 [ i , j ] [i,j] [i,j]确定为回文子串,即进行下一步需要确定当前步骤是正确的。(符合最优化原理)

  • 第一步:确定起始位置,以此为中心向左右延申。
  • 第二步:判断左右步长为1位置的字符是否相等,如果不相等则改变起始位置,反之步长加一重复第二步。
  • 第三步:在第二步的过程中记录回文子串的长度,由于只要求输出一个值,所以对当前回文子串与已记录的子串进行比较,若长度更长则更新记录,负责不变。

需要考虑以下情况:
{ P ( i , j ) = T r u e P ( i , j + 1 ) = ( S i = = S j ) P ( i , j ) = P ( i + 1 , j − 1 ) ∧ ( S i = = S j ) \left\{ \begin{aligned} P(i,j) & = & True \\ P(i,j+1) & = & (S_i==S_j) \\ P(i,j) & = & P(i+1,j-1)∧(S_i==S_j) \end{aligned} \right. P(i,j)P(i,j+1)P(i,j)===True(Si==Sj)P(i+1,j1)(Si==Sj)

d p [ i ] [ j ] dp[i][j] dp[i][j] 表示子串 s [ i . . j ] s[i..j] s[i..j] 是否为回文子串,这里子串 s [ i . . j ] s[i..j] s[i..j] 定义为左闭右闭区间,可以取到 s [ i ] s[i] s[i] s [ j ] s[j] s[j]
d p [ i ] [ j ] = ( s [ i ] = = s [ j ] ) a n d d p [ i + 1 ] [ j − 1 ] dp[i][j] = (s[i] == s[j]) and dp[i + 1][j - 1] dp[i][j]=(s[i]==s[j])anddp[i+1][j1]

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n=len(s)
        res=(0,'') #res[0]记录长度,res[1]记录回文子串
        dp=[[0]*n for _ in range(n)]
        for j in range(n):
            for i in range(j+1):
                if s[i]==s[j] and (j-i+1<=3 or dp[i+1][j-1]):
                #当子串长度为1或2时,判断本身是否构成回文子串
                #当子串长度大于等于3时,检查dp[i+1][j-1]是否构成回文子串
                    dp[i][j]=1
                    cur=s[i:j+1]
                    if len(cur)>res[0]:
                        res=(len(cur),cur)
        return res[1]

暴力法

由长到短枚举所有可能子串,直到找到第一个回文子串
可以用双指针优化

class Solution:
    def longestPalindrome(self, s: str) -> str:
        for s_length in range(len(s),-1,-1):
            for i in range(0, len(s)-s_length+1):
                sub_string = s[i:i+s_length]
                if sub_string == sub_string[::-1]:
                    return sub_string

你可能感兴趣的:(leetcode)