最长回文子串

力扣题:5. 最长回文子串 - 力扣(Leetcode)

目录

题目描述

求解方法:动态规划

 代码


题目描述

给你一个字符串 s,找到 s 中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

回文串:一个字符串正着读和反着读一样,例如:aba, 上海自来水来自海上。

求解方法:动态规划

  1. 设给定的字符串为ababad,如果是一个回文子串,那么两端的值一定相同

    dp[i] == dp[j]

  2. 如果子字符串的两端字符一样,中间的字符个数为0或1,那么这个子字符串一定是回文串。即aba,bb形式。

    j -1 - (i + 1) + < 2  推出 j - i <3

  3. 如果子字符串的两端字符相同,中间的字符个数超过2个,其子字符串的情况就是该字符串的情况,例如ababa,子串串长度为5,两端字符相同,如果中间子字符串为回文串,那么该字符串就是回文串,所以判断一个字符串是否为回文串,先判断小的字符串,再判断长的字符串。

    dp[i][j] = dp[i + 1][j - 1]

  4. 该过程可以用一个二维表表示。T表示[i,j]的下标从  i  到  j  子字符串是回文串。
最长回文子串_第1张图片 回文子串的二维表表示

 代码

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        if n < 2:
            return s
        
        max_len = 1
        begin = 0

        # 定义一个二位数组,对角线上值为True
        dp = [[False] * n for _ in range(n)]
        for i in range(n):
            dp[i][i] = True
        

        for L in range(2, n + 1):
            for i in range(n):
                j = L + i - 1 

                # 如果下标越界,break
                if j >= n:
                    break
                
                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]
                # 如果从i到j的子字符串为回文子串,那么记录这个子字符串的开始位置和长度。
                if dp[i][j] and j - i + 1 > max_len:
                    max_len = j - i + 1
                    begin = i
        return s[begin: begin + max_len]

你可能感兴趣的:(每日一学,leetcode,算法,动态规划)