LeetCode【0005】最长回文子串

本文目录

  • 1 中文题目
  • 2 求解思路
    • 2.1 基础解法:暴力解法
    • 2.2 优化解法:中心拓展法
    • 2.3 最优解法:Manacher算法
  • 3 题目总结

1 中文题目

给你一个字符串 s s s,找到 s s s 中最长的回文子串。回文串是一个正读和反读都相同的字符串.

示例 1:

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

示例 2:

  • 输入: s = " c b b d " s = "cbbd" s="cbbd"
  • 输出: " b b " "bb" "bb"

提示:

  • 1 ≤ s . l e n g t h ≤ 1000 1 \leq s.length\leq 1000 1s.length1000
  • s s s 仅由数字和英文字母组成

2 求解思路

2.1 基础解法:暴力解法

思路
遍历所有可能的子串,对每个子串判断是否为回文串,并更新最长回文串的信息

  • 步骤1: 外层循环确定子串起始位置
  • 步骤2: 内层循环确定子串结束位置
  • 步骤3: 判断当前子串是否为回文串
  • 步骤4: 如果是回文串且长度更长,则更新记录
  • 步骤5: 返回最长的回文子串

Python代码

class Solution:def longestPalindrome(self, s: str) -> str:"""寻找字符串中的最长回文子串 - 暴力解法Args:s: 输入字符串Returns:返回最长的回文子串"""def isPalindrome(start: int, end: int) -> bool:"""判断子串是否为回文串的辅助函数Args:start: 子串的起始索引end: 子串的结束索引Returns:如果是回文串返回True,否则返回False"""# 使用双指针从两端向中间移动while start < end:# 如果对应位置的字符不相等,则不是回文串if s[start] != s[end]:return False# 向中间移动start += 1end -= 1return True# 获取字符串长度n = len(s)# 特殊情况处理:空串或单字符if n < 2:return s# 记录最长回文子串的长度max_len = 1# 记录最长回文子串的起始位置start = 0# 外层循环:子串的起始位置for i in range(n):# 内层循环:子串的结束位置for j in range(i + 1, n):# 当前子串长度sub_len = j - i + 1# 如果当前子串长度大于已知最大长度,并且是回文串if sub_len > max_len and isPalindrome(i, j):# 更新最大长度和起始位置max_len = sub_lenstart = i# 返回最长回文子串return s[start:start + max_len]

时空复杂度分析

  • 时间复杂度分析
    • 外层循环,遍历所有起始位置: O ( n ) O(n) O(n)
    • 内层循环,对每个起始位置遍历所有可能的结束位置: O ( n ) O(n) O(n)
    • 判断回文: O ( n ) O(n) O(n)

总复杂度: O ( n ) ∗ O ( n ) ∗ O ( n ) = O ( n 3 ) O(n) * O(n) * O(n) = O(n³) O(n)O(n)O(n)=O(n3)

  • 空间复杂度分析:O(1)
    • 只使用了常数个变量
    • 不需要额外的数组或矩阵
    • 没有递归调用栈

2.2 优化解法:中心拓展法

思路
回文串是以中心点对称的,从每个可能的中心点向两边扩展,分别处理奇数长度和偶数长度的情况

  • 步骤1: 遍历每个可能的中心点
  • 步骤2: 对每个中心点,分别处理奇数和偶数长度的情况
  • 步骤3: 从中心向两边扩展,直到不满足回文条件
  • 步骤4: 记录并更新最长回文子串的位置
  • 步骤5: 返回最长的回文子串

python代码

class Solution:def longestPalindrome(self, s: str) -> str:"""使用中心扩展法查找最长回文子串Args:s: 输入字符串Returns:返回最长的回文子串"""def expandAroundCenter(left: int, right: int) -> tuple:"""从中心向两端扩展,寻找最长回文子串Args:left: 左边界起始位置right: 右边界起始位置Returns:返回扩展后的左右边界位置"""# 当左右指针都在有效范围内,且对应字符相等时继续扩展while left >= 0 and right < len(s) and s[left] == s[right]:# 向左扩展left -= 1# 向右扩展right += 1# 返回最后一次有效的回文串边界# left + 1: 因为while循环中left多减了1# right - 1: 因为while循环中right多加了1return left + 1, right - 1# 特殊情况处理if not s or len(s) < 2:return s# 记录最长回文子串的起始和结束位置start = 0end = 0# 遍历每个可能的中心点for i in range(len(s)):# 处理奇数长度的回文串,以单个字符为中心left1, right1 = expandAroundCenter(i, i)# 处理偶数长度的回文串,以两个字符之间的空隙为中心left2, right2 = expandAroundCenter(i, i + 1)# 更新最长回文子串的位置# 比较当前找到的两种回文串和之前找到的回文串的长度if right1 - left1 > end - start:start, end = left1, right1if right2 - left2 > end - start:start, end = left2, right2# 返回最长回文子串return s[start:end + 1]

时空复杂度分析

  • 时间复杂度分析: O ( n 2 ) O(n²) O(n2)
    • 遍历中心点,奇数长度共有n个可能的中心点;偶数长度共有n-1个可能的中心点: O ( n ) O(n) O(n)
    • 中心扩展,每次扩展最多需要n/2次比较: O ( n ) O(n) O(n)

总复杂度: O ( n ) ∗ O ( n ) = O ( n 2 ) O(n) * O(n) = O(n²) O(n)O(n)=O(n2)

  • 空间复杂度分析: O ( 1 ) O(1) O(1)
    • 只需要常数个变量记录位置信息
    • 不需要额外的数组或矩阵
    • 没有递归调用栈

2.3 最优解法:Manacher算法

思路
通过预处理将所有可能的中心点变成奇数形式,利用回文串的对称性质避免重复计算,记录并复用之前计算的结果。

  • 步骤1: 字符串预处理
    • 在字符间插入特殊字符’#’
    • 统一奇偶长度的回文串处理方式
  • 步骤2: 初始化状态
    • 初始化p数组
    • 设置center和right初始值
  • 步骤3: 遍历处理每个位置
    • 利用对称性获取初始回文半径
    • 进行中心扩展
    • 更新最大右边界和中心点
    • 更新最长回文串信息
  • 步骤4: 还原结果
    • 将处理后的结果转换回原始字符串

python代码

class Solution:def longestPalindrome(self, s: str) -> str:"""使用Manacher算法查找最长回文子串Args:s: 输入字符串Returns:返回最长的回文子串"""# 特殊情况处理if not s or len(s) < 2:return s# Step 1: 预处理字符串,插入特殊字符 '#'# 例如:"abc" -> "#a#b#c#"t = '#' + '#'.join(s) + '#'n = len(t)# p[i]数组记录以i为中心的回文半径(不包括中心点)p = [0] * n# 维护已找到的回文子串的最右边界right及其对应的中心点centercenter = 0  # 当前最大回文串的中心位置right = 0   # 当前最大回文串的右边界# 记录最长回文串的相关信息max_len = 0  # 最长回文串的长度max_center = 0  # 最长回文串的中心位置# Step 2: 核心算法部分for i in range(n):if i < right:# 利用回文串的对称性,获取初始回文半径# mirror是i关于center的对称点mirror = 2 * center - i# 避免超出right边界,取较小值p[i] = min(right - i, p[mirror])# Step 3: 中心扩展# 尝试扩展回文串的范围left = i - (p[i] + 1)  # 当前回文串的左边界r = i + (p[i] + 1)     # 当前回文串的右边界# 在不越界的情况下继续扩展while left >= 0 and r < n and t[left] == t[r]:p[i] += 1left -= 1r += 1# Step 4: 更新right和center# 如果新的回文串的右边界超过了当前的rightif i + p[i] > right:center = iright = i + p[i]# Step 5: 更新最长回文串的信息if p[i] > max_len:max_len = p[i]max_center = i# Step 6: 还原原始字符串中的回文子串# 去除特殊字符'#',计算在原字符串中的起始位置和长度start = (max_center - max_len) // 2return s[start: start + max_len]

时空复杂度分析

  • 时间复杂度分析
    • 预处理字符串: O ( n ) O(n) O(n)
    • 主循环处理: O ( n ) O(n) O(n)
    • 中心扩展:均摊 O ( 1 ) O(1) O(1)

时间总体复杂度: O ( n ) O(n) O(n)

  • 空间复杂度分析: O ( n ) O(n) O(n)
    • p数组: O ( n ) O(n) O(n)
    • 预处理后的字符串: O ( n ) O(n) O(n)
    • 其他变量: O ( 1 ) O(1) O(1)

总空间复杂度: O ( n ) O(n) O(n)


3 题目总结

题目难度: 中等
数据结构: 字符串
应用算法:Manacher算法、双指针

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/12412.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

沈阳乐晟睿浩科技有限公司引领新潮流

在当今数字化浪潮汹涌的时代&#xff0c;电子商务以其独特的魅力和无限潜力&#xff0c;正深刻改变着人们的消费习惯与商业模式。沈阳乐晟睿浩科技有限公司&#xff08;以下简称“乐晟睿浩”&#xff09;&#xff0c;作为电商领域的一颗璀璨新星&#xff0c;凭借其深厚的技术实…

【一步步开发AI运动小程序】二十一、如果将AI运动项目配置持久化到后端?

**说明&#xff1a;**本文所涉及的AI运动识别、计时、计数能力&#xff0c;都是基于云智「Ai运动识别引擎」实现。云智「Ai运动识别」插件识别引擎&#xff0c;可以为您的小程序或Uni APP赋于原生、本地、广覆盖、高性能的人体识别、姿态识别、10余种常见的运动计时、计数识别及…

Python栈--深度优先搜索(迷宫问题)

给一个二维列表&#xff0c;表示迷宫(0表示给出算法&#xff0c;求通道&#xff0c;1表示围墙)。 给出算法&#xff0c;求一条走出迷宫的路径。 maze [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 0, 0, 0, 1, 0, 1], [1, 0, 0, 1, 0, 0, 0, 1, 0, 1], […

安卓主板_基于联发科MTK MT8788平台平板电脑方案_安卓核心板开发板定制

联发科MT8788安卓核心板平台介绍&#xff1a; MTK8788设备具有集成的蓝牙、fm、wlan和gps模块&#xff0c;是一个高度集成的基带平台&#xff0c;包括调制解调器和应用处理子系统&#xff0c;启用LTE/LTE-A和C2K智能设备应用程序。该芯片集成了工作在2.0GHz的ARM Cortex-A73、最…

LabVIEW 版本控制

在软件开发中&#xff0c;版本控制系统&#xff08;VCS&#xff09; 是管理代码版本变化的核心工具。对于 LabVIEW 用户&#xff0c;虽然图形化编程带来高效开发体验&#xff0c;但由于其特有的二进制 VI 文件格式&#xff0c;传统文本比较工具无法直接用于 LabVIEW 项目。这时…

centos7.9部署oracle19c教程

1.安装前准备 1.1关闭防火墙和selinux systemctl stop firewalld systemctl disable firewalldvi /etc/selinux/config1.2 安装依赖 yum install -y unzip compat-libcap1 compat-libstdc-33 gcc-c ksh libaio-devel libstdc-devel elfutils-libelf-devel fontconfig-devel …

034集——JIG效果实现(橡皮筋效果)(CAD—C#二次开发入门)

可实现效果如下&#xff08;对象捕捉F3需打开&#xff0c;否则效果不好&#xff09;&#xff1a; public class CircleJig : EntityJig{public static void DraCJig(){PromptPointResult ppr Z.ed.GetPoint("a");if (ppr.Value null) return;Point3d pt ppr.Value…

Softing工业将在纽伦堡SPS 2024上展示Ethernet-APL现场交换机

今年&#xff0c;Softing工业将在纽伦堡SPS贸易展览会上展示aplSwitch Field —— 一款先进的过程自动化解决方案。这款16端口以太网高级物理层&#xff08;APL&#xff09;现场交换机的防护等级高达IP30&#xff0c;可提供从应用到现场级别的无缝以太网连接&#xff0c;专为Ex…

鸿蒙UI开发——小图标的使用

1、前 言 鸿蒙SDK中为我们提供了大量的高质量内置图标&#xff0c;图标详见(https://developer.huawei.com/consumer/cn/design/harmonyos-symbol/) 图标资源一览&#xff1a; 除了基本的图标图形外&#xff0c;我们还可以支持图标的多种填充模式&#xff08;单色、多色、分层…

python3的基本数据类型:Dictionary(字典)的创建

一. 简介 本文开始简单学习一下 python3中的一种基本数据类型&#xff1a;Dictionary&#xff08;字典&#xff09;。 字典&#xff08;dictionary&#xff09;是Python中另一个非常有用的内置数据类型。 二. python3的基本数据类型&#xff1a;Dictionary&#xff08;字典&…

2024 年使用 Postman 调用 WebService 接口图文教程

使用 Postman 调用 WebService 接口图文教程

设计字符串类 运算符重载 C++实现 QT环境

问题&#xff1a;设计字符串类&#xff0c; 支持下面的操作 MyString s1; // 默认构造函数 MyString s2("hello"); // 含参构造函数 MyString s3(s1); // 传参构造函数 MyString s4(5, c); // 自定义构造函数 // 运算符重载 ! > < // 运算符重…

链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)

判断循环双链表是否对称 设计一个算法用于判断带头节点的循环双链表是否对称 算法思想 让left从左向右扫描&#xff0c;right从右向左扫描&#xff0c;直到它们指向同一个节点&#xff1a;left right 或相邻left->next right&#xff0c;或right->prev left&#x…

基于STM32的智能声控分类垃圾桶(论文+源码)

1系统的功能及方案设计 本次课题为基于STM32的智能声控分类垃圾桶&#xff0c;其系统整体架构如图2.1所示&#xff0c;整个系统包括了stm32f103单片机主控制器&#xff0c;LU-ASR01语音识别模块&#xff0c;WT588语音播报模块&#xff0c;舵机等器件&#xff0c;用户可以通过语…

华大单片机跑历程IO口被写保护怎么解决

一&#xff0c;说明 使用的单片机是HC32F460KETA华大单片机&#xff0c;使用的代码历程是小华单片机历程&#xff0c;具体历程在小华官网都可以找到。   在使用小华历程跑模拟IIC时&#xff0c;SCL时钟是有的&#xff0c;但是IO输入被LOCK了&#xff0c;所以在跑历程进行断点…

网络与通信实验一 网络协议分析

Wireshark的安装 https://www.wireshark.org/&#xff08;下载链接&#xff09; 具体安装步骤参考 安装步骤 点击即可自动跳转 安装后打开 输入ipconfig 选择ipv4网卡存在的设备&#xff08;我的电脑选择WiFi&#xff09; 过滤条件选择 icmp cmd下输入 ping www.baidu.com…

电脑网络丢包怎么排查优化

上网已经成为必不可少的一部分,无论是看视频、玩游戏还是办公,网络的稳定性直接影响到我们的体验。然而有时候会遇到一些问题,比如网页加载慢、视频卡顿、游戏掉线等。这些问题的背后,往往是因为网络丢包。 网络丢包检测工具分享 什么是网络丢包? 网络丢包,简单来说,就是…

从0开始学习Linux——进程管理

往期目录&#xff1a; 从0开始学习Linux——简介&安装 从0开始学习Linux——搭建属于自己的Linux虚拟机 从0开始学习Linux——文本编辑器 从0开始学习Linux——Yum工具 从0开始学习Linux——远程连接工具 从0开始学习Linux——文件目录 从0开始学习Linux——网络配置 从0开…

QT6.5+qt-quick+qml+cmake的Item布局学习

Item 是一个基础元素&#xff0c;它本身不会渲染任何东西&#xff0c;也不会提供一个窗口来显示其内容。Window 是一个可以显示内容的顶级元素&#xff0c;它通常会包含一个或多个子元素来构建用户界面。Item是全部QML可视化对象的根&#xff0c;所有可视化类型都由该类型派生出…

Cameralink转MIPI,Cameralink视频识别分析

CameraLink视频输入转MIPI极简方案&#xff0c;可直接输入到处理芯片中进行视频目标识别与跟踪