LeetCode Hot100题——5、最长回文子串

题目

给定一个字符串s,找到s中最长的回文子串。s仅由数字和英文字母组成。

示例:

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

1、思路

看到这道题,暴力想法就是直接遍历出所有的子串,对每个子串进行回文判断,并记录下最长的子串,but,时间和内存都消耗极大,遂pass。

在仔细一看好像属于动态规划的最优子结构问题,什么是动态规划?什么是最优子结构?动态规划的最优子结构问题如何解决?

动态规划

        如果能够将一整个决策过程分成若干个互相联系的阶段性决策过程,从而使得最终的整个过程达到最好的效果。各个阶段决策的选取不能任意确定,它依赖于当前面临的状态,又影响着下一个状态,这样就是把一个问题看作是一个前后关联具有链状结构的过程,称为多阶段决策问题。

        在多阶段决策问题中,各个阶段采取的决策,一般来说是与时间有关的,决策依赖于当前状态,又随即引起状态的转移,一个决策序列就是在变化的状态中产生出来的,故有“动态”的含义,称这种解决多阶段决策最优化的过程为动态规划方法。

        简单来说,就是将一个复杂问题,分解成很多子问题,并将子问题的求解结果存储起来避免重复求解,按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。

最优子结构(最优化原理)

        不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。即一个最优化策略的子策略总是最优的。那么要解决这个问题,我们首先要写出适合该问题的状态转移方程以及动态规划的边界条件。

分析

寻找字符串s的最长回文子串,对于一个长度大于2的回文串,如果去除首尾字符,它仍然是一个回文串,例如"ababa",去掉首尾,"bab"仍然为回文串,这就是动态规划的状态之间的影响关系。我们使用P(i, j)表示子串s[ i : j ]是否为回文串,那么它的动态规划的状态转移方程为:

P(i, j)=P(i+1, j-1) and ({S}_i == {S}_j)

即只有s[i+1, j-1]是回文串,并且s的第i个和j个字母相同时,s[ i : j ]才为回文串。

当s的长度为1时,一定为回文串。

当s的长度为2时,如果两个字母相同,一定为回文串。则动态规划的边界条件为:

\left\{\begin{matrix} P(i,i) = True& & \\ P(i, i+1) = ({S}_i == {S}_{i+1})& & \end{matrix}\right.

 则最长的回文串即为P(i, j)中华j - i + 1的最大值。

python

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        if n == 1:
            return s
        if n == 2:
            if s[0] == s[1]:
                return s
            else:
                return s[0]
        
        p = [[False]*n for _ in range(n)]
        max_len = 1
        start = 0
        if n > 2:
            for L in range(2, n+1): # 枚举子串长度
                for i in range(n): # i为左边界
                    j = L + i -1 # j为右边界
                    if j >= n:
                        break
                    if s[i] != s[j]:
                        p[i][j] = False
                    else:
                        if j- i < 3: # 边界条件
                            p[i][j] = True
                        else:
                            p[i][j] = p[i+1][j-1] # 状态转移方程
                    if p[i][j] and j - i + 1 > max_len:
                        max_len = j - i + 1
                        start = i
        
        return s[start: start + max_len]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,有三种方法可以解决LeetCode上的最长回文子串。 方法一是使用扩展心法优化,即从左向右遍历字符串,找到连续相同字符组成的子串作为扩展心,然后从该心向左右扩展,找到最长的回文子串。这个方法的时间复杂度为O(n²)。\[1\] 方法是直接循环字符串判断子串是否回文子串,然后得到最长回文子串。这个方法的时间复杂度为O(n³),效率较低。\[2\] 方法三是双层for循环遍历所有子串可能,然后再对比是否反向和正向是一样的。这个方法的时间复杂度也为O(n³),效率较低。\[3\] 综上所述,方法一是解决LeetCode最长回文子串的最优解法。 #### 引用[.reference_title] - *1* [LeetCode_5_最长回文子串](https://blog.csdn.net/qq_38975553/article/details/109222153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Leetcode-最长回文子串](https://blog.csdn.net/duffon_ze/article/details/86691293)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [LeetCode 第5最长回文子串Python3解法)](https://blog.csdn.net/weixin_43490422/article/details/126479629)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值