最长回文子串(Python,LeetCode)

LeetCode 5. 最长回文子串(python)(未完) 题目链接 题目描述: 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: “babad” 输出: “bab” 注意: “aba” 也是一个有效答案。 示例 2: 输入: “cbbd” 输出: “bb” 解题思路: 一、中心扩散法: 分别以每一个字母为中心向其两端判断字母是否相同,由于可能存在回文串长度为偶数的情况,所以需要先找到与当前词相邻... 阅读详情

目录

题目描述

解决方案

暴力法

中心扩散法

Manacher算法

代码

暴力法

中心扩散法

Manacher算法

代码走读

 暴力法

中心扩散法

Manacher算法

传送门


题目描述

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

输入/输出示例

输入babad
输出bab
解释输入的字符串中最长的回文子串为bab。注意aba也是一个正确答案。

解决方案

解决的方法大概分为以下三种:

暴力法

很明显,暴力法将选出所有子字符串可能的开始和结束位置,并检验它是不是回文。在利用Python分片的优势下,时间复杂度为 O(n^{2})。空间复杂度为 O(1)。

需要注意的是,在Python语言优势下(分片的使用)暴力法的时间复杂度并不高,但是在不支持分片功能的语言里(例如Go,虽然支持切片,但是跟Python分片还是有一定区别的),暴力法的时间复杂度会达到惊人的 O(n^{3})。

中心扩散法

暴力法虽然逻辑简单清晰,但是会带来太多的重复计算。我们通过观察发现,单个字符肯定是回文字符串。如果单个字符的左右两边拥有相邻的字符,且左右两边相邻的字符相等,那么这三个字符所组成的字符串一定就是回文字符串。按照这个逻辑依此类推,就可以找到中心字符串不断向两边扩散的最长回文串。我们通过循环可以将每个字符视为一个“中心字符”,对每一个中心字符向两边扩散,找到最长的记录,就是我们要的结果。

但是会有一种情况在上面描述的逻辑中没有考虑到:如果是长度为偶数的回文字符串,例如abba,使用上面以单个字符作为中心向两边扩散的逻辑无法找到最终结果“abba”,而是会得到一个错误的结果“a”。因此我们还要考虑对长度为偶数字符串的场景:我们选取两个相邻的字符串作为“中心”。如果这两个字符相等,那么就依次向两边扩散,如果每次扩散的最外层左右两边字符相等,那么这些字符所构成的字符串就是我们要找的回文字符串。依次遍历完全部字符串后找到的长度最大的回文子串就是我们想要的结果。

综上所述,要找到一个字符串中的最大回文子串,我们不仅要以单个字符向两边扩散求解,还要对两个相同且相邻的字符向两边扩散求解。最终对两个方法求解的结果进行比较,找到长度最大的字符串,就是我们想要的结果,即最长回文子串。

复杂度分析:时间复杂度为O(n^{2})。空间复杂度为 O(1)。

Manacher算法

Manacher算法是对中心扩散法的一种优化。因为中心扩散法要对子串长度的奇偶分别进行计算,消耗了大量的时间。如果我们对奇偶转换成统一的模式进行计算,就会减少大量的时间消耗。因此Manacher算法的核心是,将原字符串(无论奇偶)构造成一个长度完全是奇数的字符串:构造后无论是长度,还是内部字符和字符之间的距离都变成了奇数。这种构造新字符串的方式就是将原字符串的首尾和每个字符之间都插入一个特殊的标志字符。例如假设原字符串为“abba”,通过插入特殊字符的方式将字符串构造为“#a#b#b#a”。需要注意的是,该特殊字符不能存在于原始字符串中。我们对构造后的字符串利用中心扩散法的思想求出最长回文子串。

代码

暴力法

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

        return max_sub_palindrome_string

中心扩散法

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if s == s[::-1]:
            return s

        max_sub_palindrome_string = s[0]
        for index in range(len(s)):
            palindrome_odd = Solution.get_palindrome(index, index, s)
            palindrome_even = Solution.get_palindrome(index, index+1, s)
            max_sub_palindrome_string = max(
                palindrome_odd,
                palindrome_even,
                max_sub_palindrome_string,
                key=len,
            )
        return max_sub_palindrome_string

    @staticmethod
    def get_palindrome(left, right, s) -> str:
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1
            right += 1
        return s[left+1:right]

Manacher算法

class Solution:
    def longestPalindrome(self, s: str) -> str:
        return self.manacher(s)

    @staticmethod
    def manacher(s: str) -> str:
        if len(s) < 2:
            return s
        # 将一个可能是偶数长/奇数长的字符串,首位以及每个字符间添加#
        manacher_length = len(s)*2+1
        manacher_str = "#".join(s).center(manacher_length, "#")
        max_palindrome = ""
        for i in range(manacher_length):
            left = i - 1
            right = i + 1
            while left >= 0 and right < manacher_length and \
                    manacher_str[left] == manacher_str[right]:
                left -= 1
                right += 1

            if right - left + 1 > len(max_palindrome):
                max_palindrome = manacher_str[left+1:right]
        return max_palindrome.replace("#", "")

代码走读

 暴力法

class Solution:
    def longestPalindrome(self, s: str) -> str:
        # 如果s本身回文,或s为空字符,则返回s
        if s == s[::-1]:
            return s

        # 因为单字符本身回文,因此初始化最长子回文串为首字符
        max_sub_palindrome_string = s[0]

        # 设置两个游标变量,i从头到尾-1依次遍历,将每个字符作为子串的首字符
        # j 作为子串的尾字符, 依次检查s[i:j+1]是否为最长回文串
        for i in range(len(s)-1):
            for j in range(i+1, len(s)):
                if j - i + 1 > len(max_sub_palindrome_string) and \
                        s[i:j+1] == s[i:j+1][::-1]:
                    max_sub_palindrome_string = s[i:j+1]

        return max_sub_palindrome_string

# 自测用例
if __name__ == '__main__':
    s = Solution()
    result = s.longestPalindrome("hada")
    print(result)

中心扩散法

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if s == s[::-1]:
            return s

        max_sub_palindrome_string = s[0]
        for index in range(len(s)):
            # 分别以奇数子串和偶数子串为中心向两边扩散,找出最长子串
            palindrome_odd = Solution.get_palindrome(index, index, s)
            palindrome_even = Solution.get_palindrome(index, index+1, s)
            max_sub_palindrome_string = max(
                palindrome_odd,
                palindrome_even,
                max_sub_palindrome_string,
                key=len,
            )
        return max_sub_palindrome_string

    # 以s[left:right+1]为中心向两边扩散,寻找最长回文子串
    @staticmethod
    def get_palindrome(left, right, s) -> str:
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1
            right += 1
        return s[left+1:right]


# 自测用例
if __name__ == '__main__': 
    s = Solution() 
    result = s.longestPalindrome("babad") 
    print(result)

Manacher算法

class Solution:
    def longestPalindrome(self, s: str) -> str:
        return self.manacher(s)

    @staticmethod
    def manacher(s: str) -> str:
        # 如果s是单字符的字符串,那么直接返回
        if len(s) < 2:
            return s
    
        # 将一个可能是偶数长/奇数长的字符串,首位以及每个字符间添加#,确保添加后变成了长度为奇数的字符串
        manacher_length = len(s)*2+1
        manacher_str = "#".join(s).center(manacher_length, "#")

        # 记录最长子回文串
        max_palindrome = ""
        for i in range(manacher_length):
            left = i - 1
            right = i + 1
            while left >= 0 and right < manacher_length and \
                    manacher_str[left] == manacher_str[right]:
                left -= 1
                right += 1

            # 将左右指针回退一位,得到本次遍历的回文串长度:(right - 1) - (left + 1) - 1 = right - left - 1
            if right - left - 1 > len(max_palindrome):
                max_palindrome = manacher_str[left+1:right]
 
        # 由于max_palindrom是包含特殊字符#的回文子串,因此需要将#字符删除后返回
        return max_palindrome.replace("#", "")


# 自测用例
if __name__ == '__main__':
    s = Solution()
    result = s.longestPalindrome("babad")
    print(result)

传送门

LeetCode试题链接

len()函数

range()函数

str.join()方法

str.center()方法

str.replace()方法

python【力扣LeetCode算法题库】5- 最长回文子串 5. 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: “babad” 输出: “bab” 注意: “aba” 也是一个有效答案。 示例 2: 输入: “cbbd” 输出: “bb” 中心扩展方法 思路:扫一遍字符串s,对于回文子串长为奇数的情况,求s[i]为轴对称中心的回文子串最长值;回文子串长偶数的情况,求s[i]s... 阅读详情

相关推荐

FPGA时序分析中的工艺角:从PVT原理到建立保持时间验证

在数字电路设计中,静态时序分析(STA)是确保芯片功能正确和性能达标的核心验证手段。其基本原理是通过计算信号在逻辑路径上的传播延迟,检查建立时间和保持时间是否满足寄存器采样要求。这项技术的核心价值在于,它能在芯片制造前就预测并消除时序违规,极大提高设计成功率。然而,实际芯片性能会受到工艺波动、电压变化和温度漂移(合称PVT)的显著影响。为了覆盖这些不确定性,时序分析必须采用基于工艺角的边界模型——用最慢的工艺角模型验证建立时间,用最快的工艺角模型验证保持时间。这种分析方法广泛应用于FPGA和ASIC设计流程

weixin_30181209的博客 196

Python最长回文子串

# 1.暴力解法(Brute Method) """ 暴力求解是最容易想到的,要截取字符串的所有子串,然后再判断这些子串中哪些是回文的,最后返回回文子串中最长的即可。 这里我们可以使用两个变量,一个记录最长回文子串开始的位置,一个记录最长回文子串的长度,最后再截取。 """ class Solution: def longestPalindrome(self, s): if (len(s) < 2): return s start .

weixin_42698464的博客 6751

VSCode玩转ESP-ADF音频开发:从环境搭建到成功播放MP3的避坑全流程

本文详细介绍了如何在VSCode环境下使用ESP-ADF框架进行ESP32音频开发,从环境搭建到成功播放MP3的全流程。重点解析了`IDF_PATH`和`ADF_PATH`的配置问题,以及如何解决`xTaskCreateRestrictedPinnedToCore`等常见编译错误,帮助开发者快速上手ESP-ADF音频开发。

weixin_42520909的博客 339

Leetcode分割回文串

给定一个字符串s,将s分割成一些子串,使每个子串都是回文串。 返回符合要求的最少分割次数。 示例: 输入:"aab" 输出: 1 解释: 进行一次分割就可将s 分割成 ["aa","b"] 这样两个回文子串。 class Solution: def minCut(self, s: str) -> int: dp=[[0 for i in range...

weixin_39025364的博客 212

Homebrew 必备软件清单:我的 macOS 开发环境搭建全记录

本文详细介绍了如何使用Homebrew在macOS上搭建高效的开发环境,包括基础配置、核心开发工具链、高效编码工具集等30个必备工具。通过Homebrew这一macOS缺失的包管理器,开发者可以一键安装命令行工具和GUI应用,大幅提升工作效率。文章还提供了日常维护命令和疑难问题解决方案,适合从新手到资深开发者的所有用户。

weixin_28836507的博客 353

传输线的特征阻抗

信号源内阻与所接传输线的特性阻抗大小相等且相位相同,或传输线的特性阻抗与所接负载阻抗的大小相等且相位相同,分别称为传输线的输入端或输出端处于阻抗匹配状态,简称为阻抗匹配。否则,便称为阻抗失配。有时也直接叫做匹配或失配。指一个电路输入端的等效阻抗。在输入端上加上一个电压源U,测量输入端的电流I,则输入阻抗Rin就是U/I。可以把输入端想象成一个电阻的两端,这个电阻的阻值,就是输入阻抗。- 对于电压驱动的电路,输入阻抗越大,则对电压源的负载就越轻,因而就越容易驱动,也不会对信号源有影响;

学海无涯的专栏 4462

LeetCode(Python3)5.最长回文子串

Question: Given a strings, returnthe longest palindromic substringins. Example1: Input: s = "babad" Output: "bab" Explanation:"aba" is also a valid answer. Example2: Input: s = "cbbd" Output: "bb" Mentality: 这道题可以用中心扩散法来解,依次判断我们子串所能达到的最...

weixin_52593484的博客 1536

YOLOv8使用设备摄像头实时监测

YOLOv8使用设备摄像头实时监测

Joining667的博客 4187

最长回文子串:中心扩散法python实现

class Solution: def longestPalindrome(self, s: str) -> str: lenStr = len(s) maxLen = 0 tempLen = 0 maxStr = '' leftDigit = 0 rightDigit = 0 if lenStr == 1 or s =='': return s .

caulfieldd的博客 527

ABAP CDS View 从入门到精通教程第一篇:ABAP CDS View 在 SAP 技术体系中的重要地位

摘要:本文介绍了SAP开发技术专家提供的多套SAP开发教程,涵盖ABAP、UI5、Fiori、OData、BTP等技术领域。重点阐述了ABAP CDS View在SAP S/4HANA中的核心地位,作为虚拟数据模型(VDM)的关键技术,它实现了OLTP和OLAP的统一处理。文章还说明了学习CDS View的前置条件,包括需要SAP NetWeaver 7.50 SP01或更高版本系统,以及使用SAP ABAP Development Tool进行开发实践。作者具有16年SAP开发经验,这些教程形成了完整的S

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 895

复旦微FMSH_Procise安装全流程详解:从环境配置到实战避坑指南

通过本文的全流程解析+实战技巧,开发者可快速掌握Procise在复旦微芯片开发中的核心应用。未来随着AKConv轻量级架构(参考往期文章)等创新技术的融入,国产芯片开发生态将更加完善。立即关注本专栏,获取最新多镜像切换指南与Linux SDK实战教程!扩展阅读复旦微在线升级BOOT.BIN全解析H7-TOOL实现复旦微脱机烧录(注:本文实验环境为Windows 10 x64 + FMQL45T-CORE开发板,部分操作可能因版本更新调整)立即行动下载本文配套配置文件:[GitHub链接]加入技术交流群。

QQ_778132974的博客 3231

力扣刷题(python)50天——第三天:最长回文子串

力扣刷题(python)50天——第三天:最长回文子串 题目描述 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: “babad” 输出: “bab” 注意: “aba” 也是一个有效答案。 示例 2: 输入: “cbbd” 输出: “bb” 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/probl...

weixin_44568780的博客 395

手把手教你学Simulink--基于车联网与智能交通系统的场景实例:基于车联网(V2X)的实时路况信息共享与处理

《基于Simulink的车联网(V2X)实时路况共享系统仿真》摘要:本文详细介绍使用Simulink构建V2X智能交通系统的完整方法。系统包含交通路网建模、V2X通信实现(支持DSRC/C-V2X标准)、多源路况信息融合、动态路径规划等核心模块。通过对比实验,验证V2X可使平均车速提升52%,行程时间缩短34%,显著提升交通效率。文章还探讨了AI预测调度、车辆编队等高级应用,为智慧交通系统开发提供实用参考。所需工具包括Simulink、SimEvents及无线通信工具箱等。

MHD0815的博客 737

力扣 leetcode 5. 最长回文子串(python)

Topic 给你一个字符串 s,找到 s 中最长的回文子串。 Example_1 输入:s = “babad” 输出:“bab” 解释:“aba” 同样是符合题意的答案。 Example_2 输入:s = “cbbd” 输出:“bb” Example_3 输入:s = “a” 输出:“a” Example_4 输入:s = “ac” 输出:“a” Tips 1 <= s.length <= 1000 s 仅由数字和英文字母(大写和/或小写)组成 Solution 本题可以采用

weixin_50791900的博客 437

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

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

题目描述 给你一个字符串 s,找到 s 中最长的回文子串。 题解:动态规划 这是一道很经典的题目。首先我想到了动态规划算法: 对于子串s[i…j],它为回文子串的条件为:s[i+1 … j-1]为回文子串,且s[i]==s[j]。想到这里,状态转移方程就已经显然易见了。 那么初始状态呢?我们的状态转移方程是从短的子串向长的子串转移的,因此外循环应该是子串长度。当子串长度为1,也就是只有一个字符时,显然为回文子串,这就是初始状态。 由于要返回最长的回文子串(SJ),因此需要记录一下。 该算法的时间复杂度为O(

乔卿的博客 1814

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【LeetCode力扣】005.最长回文子串(Python)

时间,空间复杂度都是O(2^n)

Yophan的博客 442

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

力扣的最长回文子串解法(Python3)

力扣的最长回文子串解法 题目描述: 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: “babad” 输出: “bab” 注意: “aba” 也是一个有效答案。 示例 2: 输入: “cbbd” 输出: “bb” 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-pal...

chutu2018的博客 290

python最长回文子串leetcode_Leetcode最长回文子串问题

LeetCode第五题,最长回文子串问题,其中Python下面有一种解法,原理有点看不懂,英文描述如下:Basic thought is simple. when you increase s by 1 character, you could only increase maxPalindromeLen by 1 or 2, and that new maxPalindrome includes...

weixin_39946657的博客 114

LeetCode最长回文子串解题思路Python JavaScript

LeetCode解题记录

kllwlick的博客 448

Leetcode刷题5--- 最长回文子串 Python

Leetcode刷题5--- 最长回文子串 Python

PeterClerk的博客 842

力扣:(5)最长回文子串(Python)

给你一个字符串s,找到s中最长的 回文 子串。

2503_91125378的博客 397

4. Leetcode-最长回文子串(python)

给你一个字符串s,找到s中最长的 回文 子串。"bab""aba" 同样是符合题意的答案。

m0_74930453的博客 415

5. 最长回文子串(LeetCode-力扣-Python)

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。"aba" 同样是符合题意的答案。

zy20221209的博客 448

python-leetcode-最长回文子串

【代码】python-leetcode-最长回文子串。

Lucy_wzw的博客 249

力扣 (LeetCode)刷题笔记5.最长回文子串 python

给你一个字符串 s,找到 s 中最长的回文子串。 示例 1: 输入:s = “babad” 输出:“bab” 解释:“aba” 同样是符合题意的答案。 示例 2: 输入:s = “cbbd” 输出:“bb” 示例 3: 输入:s = “a” 输出:“a” 示例 4: 输入:s = “ac” 输出:“a” 提示: 1 <= s.length <= 1000 s 仅由数字和英文字母(大写和/或小写)组成 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/probl

Nothing is final!!! 458

leetcode 17 最长回文子串 python

leetcode 最长回文子串 python 对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。 给定字符串A以及它的长度n,请返回最长回文子串的长度。 class Solution: def getLongestPalindrome(self, A, n): # write code here maxlen=0 for i in range(n): numa=A[i-maxlen-1:i+1]

q339179198的博客 206
上一篇: Go int类型的最大值和最小值
下一篇: 最长回文子串(Go,LeetCode)
TCatTime
博客等级 码龄9年 400粉丝 256原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值