LeetCode题目(Python实现):最长回文子串_RexT1的博客-程序员秘密

技术标签: 算法  LeetCode题目  python  字符串  leetcode  数据结构  

题目

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

示例1 :

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例2 :

输入: "cbbd"
输出: "bb"

想法一:以每个字符为中心向两边扫描

算法实现

def longestPalindrome(self, s: str) -> str:
    if not s:
        return ""
    res = s[0]
    n = len(s)
    for i in range(1, n):
        # 中轴情况
        j = 1
        while i - j > -1 and i + j < n and s[i - j] == s[i + j]:
            j += 1
        j -= 1
        if len(res) < j * 2 + 1:
            res = s[i - j:i + j + 1]

        # 对称情况
        j = 1
        while i - j > -1 and i + j - 1 < n and s[i - j] == s[i + j - 1]:
            j += 1
        j -= 1
        if len(res) < j * 2:
            res = s[i - j:i + j]
    return res

执行结果

执行结果 : 通过
执行用时 : 1176 ms, 在所有 Python3 提交中击败了68.60%的用户
内存消耗 : 13.6 MB, 在所有 Python3 提交中击败了33.03%的用户
在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n^2)

  • 空间复杂度:O(1)

动态规划

算法实现

def longestPalindrome(self, s: str) -> str:
    size = len(s)
    if size < 2:
        return s

    dp = [[False for _ in range(size)] for _ in range(size)]

    max_len = 1
    start = 0

    for i in range(size):
        dp[i][i] = True

    for j in range(1, size):
        for i in range(0, j):
            if s[i] == s[j]:
                if j - i < 3:
                    dp[i][j] = True
                else:
                    dp[i][j] = dp[i + 1][j - 1]
            else:
                dp[i][j] = False

            if dp[i][j]:
                cur_len = j - i + 1
                if cur_len > max_len:
                    max_len = cur_len
                    start = i
    return s[start:start + max_len]

执行结果

在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n^2)

  • 空间复杂度:O(n^2)

Manacher 算法

算法实现

def longestPalindrome(self, s: str) -> str:
    # 特判
    size = len(s)
    if size < 2:
        return s

    # 得到预处理字符串
    t = "#"
    for i in range(size):
        t += s[i]
        t += "#"
    # 新字符串的长度
    t_len = 2 * size + 1

    # 数组 p 记录了扫描过的回文子串的信息
    p = [0 for _ in range(t_len)]

    # 双指针,它们是一一对应的,须同时更新
    max_right = 0
    center = 0

    # 当前遍历的中心最大扩散步数,其值等于原始字符串的最长回文子串的长度
    max_len = 1
    # 原始字符串的最长回文子串的起始位置,与 max_len 必须同时更新
    start = 1

    for i in range(t_len):
        if i < max_right:
            mirror = 2 * center - i
            # 这一行代码是 Manacher 算法的关键所在,要结合图形来理解
            p[i] = min(max_right - i, p[mirror])

        # 下一次尝试扩散的左右起点,能扩散的步数直接加到 p[i] 中
        left = i - (1 + p[i])
        right = i + (1 + p[i])

        # left >= 0 and right < t_len 保证不越界
        # t[left] == t[right] 表示可以扩散 1 次
        while left >= 0 and right < t_len and t[left] == t[right]:
            p[i] += 1
            left -= 1
            right += 1

        # 根据 max_right 的定义,它是遍历过的 i 的 i + p[i] 的最大者
        # 如果 max_right 的值越大,进入上面 i < max_right 的判断的可能性就越大,这样就可以重复利用之前判断过的回文信息了
        if i + p[i] > max_right:
            # max_right 和 center 需要同时更新
            max_right = i + p[i]
            center = i

        if p[i] > max_len:
            # 记录最长回文子串的长度和相应它在原始字符串中的起点
            max_len = p[i]
            start = (i - max_len) // 2
    return s[start: start + max_len]

执行结果

在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n)

  • 空间复杂度:O(n^2)

小结

先按自己的想法设计,也是之前做过的题,想了很久决定每个字符向两边扫描会好一点,然后做了出来。之后看了动态规划和 Manacher 算法,基本上理解了。

Manacher 算法说白了就是利用中心扩散的信息来省去一些计算,非常厉害,然后题解里面讲的很详细,虽然看了很久才明白,但是看完以后还是觉得大致理解了,很不错。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_45556599/article/details/104829884

智能推荐

linux - make、makefile_zhang_jia_qing的博客-程序员秘密

1、源文件//function1.c#include &lt;stdio.h&gt;#include "function1.h"int fun1(int a, int b){}//function2.c#include &lt;stdio.h&gt;#include "function2.h"int fun2(int a, int b){}//main.c#include &lt;stdio.h&gt;#include "function1.h"#include "funct

unity学习笔记-Avpro和安卓结合_unity vulkan_淳杰的博客-程序员秘密

unity学习笔记Avpro问题啰嗦一下回到主题问题核心解决思路Avpro如题,Avpro是使用unity的大神们写的播放视频的插件,使用这个插件可以快捷的对视频进行播放暂停进度条的操作,可以说十分的便利他的功能在官方的package导入之后有详细的说明,这里就不多说太多这里就讲一个打包到安卓的注意事项这个可能可以帮助到很多的兄弟们问题啰嗦一下项目要求在移动端的界面里能够播放视频以前的流程就是直接通过uniwebview的插件在unity里进行显示但是老板说这样体验太差了,所以同事在网上

StarUML如何将背景变成空白_staruml背景网格怎么删掉_iceorangebub的博客-程序员秘密

原本的背景是带栅格的按 Ctrl+G 或在 View-&gt;Show Grid 目录下,把它关掉即可现在就变成空白的了~

深度学习——3D识别_深度学习立体识别_有些代码不应该被忘记的博客-程序员秘密

数据库:http://ai.stanford.edu/~jkrause/cars/car_dataset.html目标:用3D表示做车型精细识别,基于两种2D表示SPP,BubleBank。 构建了两个数据库:10-BMW,197-car,数据库在网站上下载。3D几何估计 使用3D CAD模型进行建模,精细识别的第一步是找到一个最合适图像的CAD模型。 合成数据:使

ant design vue利用rowClassName给table添加行样式_vue rowclassname加一行线_yougejing的博客-程序员秘密

ant design vue利用rowClassName给table添加行样式目录1. 需求:表格每行数据hasVerdict值不为'1'时标红显示2. 实现方式:table属性rowClassName3. 问题:样式未生效4. 解决方案4.1 方案一:删除scoped4.2 方案二:样式穿透5. 总结目录1. 需求:表格每行数据hasVerdict值不为’1’时标红显示2. 实现方式:table属性rowClassNamehtml部分代码&lt;a-table ref="table"

第二届“中科实数杯”全国电子数据取证 wp_火眼取证分析软件_1-1i111e的博客-程序员秘密

准备参加第三届的比赛了,特意把第二届的比赛写一下,第一次写wp,不足之处请多多指点案件背景:第二部分------案件背景介绍王刚(英文名kugoo)是一家国内大型电子商务公司的服务器管理员,他负责公司多台服务器的日常运维管理。王刚利用个人职位之便,私下将客户的资料卖给第三方获得高额回报。电商平台的不少客户遭受诈骗和营销推广骚扰,该企业纷纷收到投诉,公司怀疑有人泄漏了平台的用户数据。该公司聘请第三方专业取证调查公司协助开展调查,需调查王刚在职期间利用个人职位之便贩卖客户信息的行为及关键证据。在王刚

随便推点

html 翻页效果,JavaScript实现翻页功能(附效果图)_突发奇想的饭粒的博客-程序员秘密

效果图:要点:displayPage('#pageDiv','goPage','query',10,1,100);#pageDiv是显示翻页的div名称。goPage是跳转到后面的文本输入框的id,如果有需要可以根据 * 这个参数直接赋值。query是查询的方法名称。10是总页数1是当前页数100是总条数。function query(queryPage){//ajax查询表格需要的数据var q...

Potsdam,Vaihingen数据集(附百度网盘下载地址)_小了白了兔_白了又了白的博客-程序员秘密

遥感数据集Potsdam,Vaihingen 的分享及处理1. Potsdam,Vaihingen数据集下载地址(百度网盘)2. 数据集分割处理1)分割图片2)保存为.mat格式1. Potsdam,Vaihingen数据集下载地址(百度网盘)对于做遥感图像处理的同学来说,Potsdam,Vaihingen是两个常用的数据集。如果想下载,一般需要搭梯子下载,并且下载过程经常中断,百度相关文章,排名靠前的文章也没有给出国内相关下载链接,因此将自己下载的数据集分享出来,为大家提供方便。Potsdam数据

android 工作线程中更新界面,Android多线程界面更新方法的总结_weixin_32923817的博客-程序员秘密

Android多线程界面更新的方法总结Android多线程与界面交互的方法Activity.runOnUiThread(Runnable)View.post(Runnable),View.postDelay(Runnable,long)HandlerAsyncTask一、runOnUiThread的用法runOnUiThread是Activity的内部方法,使用时最好指定当前的环境变量(Conte...

Linux设备驱动开发-交叉编译环境的建立_DBPF的博客-程序员秘密

学习linux设备驱动,首先要在自己的PC机上安装linux系统,当然最好还要有一块属于自己的开发板等等,我这里用的是FriendlyARM公司的tiny6410开发板,采用的是S3C6410 ARM11处理器。这些准备工作就不再这里进行讲解了。那么下面我们就将进行设备驱动开发的第一步,建立交叉编译环境。        其实有了自己的开发板之后,开发板自带的资料都会有建立交叉编译环境大概方

谷粒商城-服务3_订单为什么要用es存储_阿门之恋的博客-程序员秘密

29、商品上架和ES的存储模型选择上架概念:我们把商品存入es的过程叫上架,只有上架的商品才能被前台检索es的数据保存位置:内存对es的使用我们不能把所有的数据都放在进来,因为内存时很贵的,我们需要有用的信息放进来,商品es的存储模型方案:模型一:占用空间多{ skuId:1 spuId:11 skuName:华为xxx attr:[ { 尺寸:5 颜色:红色 。。。 。。。 } ]}模型二:查询时间长sku索引{}spu索引{}30、nested

推荐文章

热门文章

相关标签