力扣题——最长回文子串

简介: 这里使用Python3

1、要求:给你一个字符串 s,找到 s 中最长的回文子串("回文串"是一个正读和反读都一样的字符串)

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案

2、思路与算法

对于一个子串而言,如果它是回文串,并且长度大于2,那么将它首尾的两个字母去除之后,它仍然是个回文串

根据这样的思路,我们就可以用动态规划的方法解决本题,我们用 P(i,j) 表示字符串 s 的第 i 到第 j 个字母组成的串(下文表示成 s[i:j])是否为回文串:

这里的「其它情况」包含两种可能性:

  • s[i, j]本身不是一个回文串;
  • i>j,此时 s[i, j] 本身不合法

也就是说,只有 s[i+1:j−1] 是回文串,并且 s 的第 i 和第 j 个字母相同时,s[i:j] 才会是回文串。

3、根据这个思路,我们就可以完成动态规划了,最终的答案即为所有 P(i,j)=true 中 j-i+1(即子串长度)的最大值,注意:在状态转移方程中,我们是从长度较短的字符串向长度较长的字符串进行转移的,因此一定要注意动态规划的循环顺序

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        if n < 2:
            return s
        
        max_len = 1
        begin = 0
        # dp[i][j] 表示 s[i..j] 是否是回文串
        dp = [[False] * n for _ in range(n)]
        for i in range(n):
            dp[i][i] = True
        
        # 递推开始
        # 先枚举子串长度
        for L in range(2, n + 1):
            # 枚举左边界,以长度为2开始,左边界的上限设置可以宽松一些
            for i in range(n):
                # 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
                j = L + i - 1
                # 如果右边界越界,就可以退出当前循环
                if j >= n:
                    break
                    
                if s[i] != s[j]:
                    dp[i][j] = False 
                else:
                    # 前面已经是s[i]!=s[j],下面的就是s[i]=s[j]的了
                    if j - i < 3:
                        dp[i][j] = True
                    else:
                        dp[i][j] = dp[i + 1][j - 1]
                
                # 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
                if dp[i][j] and j - i + 1 > max_len:
                    max_len = j - i + 1
                    begin = i
        return s[begin:begin + max_len]

4、额外:对于[False] * n,比如n = 4,代表生成[False, False, False, False] 向量
而 for _ in range(n)中的下划线为占位符,也就是说不在意具体变量的值,仅用来表示循环4次,生成4个[False, False, False, False],用公式最外侧[ ]形成了一个4*4的二维矩阵

相关文章
|
2月前
Leetcode第五题(最长回文子串)
这篇文章介绍了解决LeetCode第五题“最长回文子串”问题的一种方法,使用了中心扩展法来寻找给定字符串中的最长回文子串。
41 0
|
7月前
|
算法
LeetCode算法题---最长回文子串、N 字形变换(四)
LeetCode算法题---最长回文子串、N 字形变换(四)
43 0
|
4月前
|
Python
【Leetcode刷题Python】5. 最长回文子串
LeetCode 5题 "最长回文子串" 的Python解决方案,使用动态规划算法找出给定字符串中的最长回文子串。
50 3
|
4月前
|
算法
LeetCode第5题最长回文子串
该文章介绍了 LeetCode 第 5 题最长回文子串的解法,通过分析回文子串的特点,使用动态规划的思想,用二维数组记录字符串是否为回文串,从后往前遍历找子串,减少重复判断,最终找到最长回文子串,并总结了解题时通过举例推导找规律的思路。
LeetCode第5题最长回文子串
|
7月前
leetcode-5:最长回文子串
leetcode-5:最长回文子串
55 0
|
6月前
|
存储 算法 Java
【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)
【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)
83 2
|
7月前
leetcode代码记录(最长回文子串
leetcode代码记录(最长回文子串
49 2
|
7月前
|
索引
力扣---最长回文子串(动态规划)
力扣---最长回文子串(动态规划)
|
6月前
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
【LeetCode 训练营 3,5】无重复字符的最长子串+最长回文子串
【LeetCode 训练营 3,5】无重复字符的最长子串+最长回文子串
94 1