【动态规划-2】5.最长回文子串
题目描述给你一个字符串s找到s中最长的回文子串。如果字符串向前和向后读都相同则它满足回文性。子字符串是字符串中连续的非空字符序列。示例 1输入s babad输出bab解释aba 同样是符合题意的答案。示例 2输入s cbbd输出bb解题思路方法一中心扩展法(最优解)核心思路回文串一定有一个中心奇数长度中心是一个字符如aba中心是b偶数长度中心是两个字符之间如abba中心是bb之间从每个中心向两边扩展找到最长的回文。具体过程示例s babad中心 i0 (b): 扩展 → b 中心 i1 (a): 扩展 → bab 中心 i2 (b): 扩展 → aba 中心 i3 (a): 扩展 → a 中心 i4 (d): 扩展 → d 偶数中心: 中心 i0.5: 扩展 → 中心 i1.5: 扩展 → ... 最长: bab 或 aba ✅代码实现class Solution { public: string longestPalindrome(string s) { if (s.empty()) return ; int start 0, maxLen 1; for (int i 0; i s.size(); i) { // 奇数长度回文中心是 s[i] int len1 expandAroundCenter(s, i, i); // 偶数长度回文中心是 s[i] 和 s[i1] 之间 int len2 expandAroundCenter(s, i, i 1); int len max(len1, len2); if (len maxLen) { maxLen len; start i - (len - 1) / 2; } } return s.substr(start, maxLen); } private: int expandAroundCenter(string s, int left, int right) { while (left 0 right s.size() s[left] s[right]) { left--; right; } return right - left - 1; // 回文长度 } };复杂度分析维度复杂度说明时间复杂度O(n²)每个中心扩展 O(n)共 n 个中心空间复杂度O(1)只用常数个变量方法二动态规划思路dp[i][j]表示s[i..j]是否是回文。s[i] s[j]且dp[i1][j-1]为真 →dp[i][j]为真边界j - i 1时只要s[i] s[j]就是回文代码实现class Solution { public: string longestPalindrome(string s) { int n s.size(); if (n 2) return s; vectorvectorbool dp(n, vectorbool(n, false)); int start 0, maxLen 1; // 初始化单个字符都是回文 for (int i 0; i n; i) { dp[i][i] true; } // 按长度递增遍历 for (int len 2; len n; len) { for (int i 0; i len - 1 n; i) { int j i len - 1; if (s[i] s[j]) { if (len 2 || dp[i1][j-1]) { dp[i][j] true; if (len maxLen) { maxLen len; start i; } } } } } return s.substr(start, maxLen); } };复杂度时间 O(n²)空间 O(n²)方法三Manacher 算法核心思路第一步预处理统一奇偶回文有两种奇数长度aba中心是单个字符偶数长度abba中心是两个字符之间Manacher 的做法是插入特殊字符把所有回文都变成奇数长度。插入#原串: a b a 新串: # a # b # a #原串: a b b a 新串: # a # b # b # a #效果原来奇数长度aba长度3→ 新串#a#b#a#长度7中心是b原来偶数长度abba长度4→ 新串#a#b#b#a#长度9中心是#所有回文都变成奇数长度中心唯一。再加两个哨兵新串: ^ # a # b # a # $^和$是哨兵防止扩展时越界它们不相等扩展到这里一定停止第二步定义半径数组pp[i]表示以i为中心的回文半径包含中心。以#a#b#a#为例i字符p[i]回文0#0#1a1#a#2#0#3b3#a#b#a#4#0#5a1#a#6#0#原串回文长度 p[i]因为插入#后半径正好等于原串回文长度。原串起始位置 (i - p[i]) / 2。第三步核心——利用对称性关键变量center当前最右回文的中心right当前最右回文的右边界center p[center]核心思想当遍历到i时如果i right说明i在某个回文内部。利用对称性i关于center的对称点是mirror 2 * center - i此时p[i]至少等于p[mirror]但有两种情况情况1: p[mirror] right - i → p[i] p[mirror]完全对称 情况2: p[mirror] right - i → p[i] right - i只能确定这么多需要继续扩展统一写法if (i right) { p[i] min(right - i, p[mirror]); }图解center ↓ ... [ ... i ... ] ... ↑ ↑ mirror right i 和 mirror 关于 center 对称第四步继续扩展确定p[i]的下界后继续向两边扩展while (t[i p[i] 1] t[i - p[i] - 1]) { p[i]; }因为加了哨兵^和$不会越界。第五步更新center和right如果i p[i] right说明找到了更靠右的回文更新if (i p[i] right) { center i; right i p[i]; }用例子走一遍s babad预处理t ^#b#a#b#a#d#$ 下标: 0 1 2 3 4 5 6 7 8 9 10 11 12遍历it[i]mirrorrightp[i]说明1#-00扩展失败2b-01#b#3#-00扩展失败4a-03#b#a#b#center4, right75#370irightp[5]min(2, p[3]0)06b271irightp[6]min(1, p[2]1)17#170iright扩展失败8a-71iright扩展#a#9#-7010d-71#d#maxLen 3, maxCenter 4start (4 - 3) / 2 0 结果 s.substr(0, 3) bab ✅代码实现class Solution { public: string longestPalindrome(string s) { // 预处理插入 # 变成奇数长度 string t ^#; for (char c : s) { t c; t #; } t $; int n t.size(); vectorint p(n, 0); int center 0, right 0; int maxLen 0, maxCenter 0; for (int i 1; i n - 1; i) { if (i right) { p[i] min(right - i, p[2 * center - i]); } while (t[i p[i] 1] t[i - p[i] - 1]) { p[i]; } if (i p[i] right) { center i; right i p[i]; } if (p[i] maxLen) { maxLen p[i]; maxCenter i; } } int start (maxCenter - maxLen) / 2; return s.substr(start, maxLen); } };复杂度分析维度复杂度说明时间复杂度O(n)每个字符最多被扩展一次空间复杂度O(n)p 数组 预处理字符串为什么是 O(n)因为right只增不减每次扩展都会增加right总扩展次数不超过 n。三种方法对比方法时间复杂度空间复杂度代码复杂度推荐度中心扩展O(n²)O(1)简单⭐⭐⭐⭐⭐动态规划O(n²)O(n²)中等⭐⭐⭐⭐ManacherO(n)O(n)复杂⭐⭐⭐中心扩展是面试首选代码简洁空间 O(1)时间复杂度 O(n²) 对大多数场景够用。关键细节1. 为什么中心扩展要处理奇偶两种情况奇数回文aba中心是单个字符偶数回文abba中心是两个字符之间所以需要对每个位置调用两次扩展expand(i, i)和expand(i, i1)。2. 为什么返回right - left - 1循环结束时left和right已经越界或不匹配。回文长度 (right - 1) - (left 1) 1 right - left - 1。3. 动态规划的遍历顺序必须按长度递增遍历因为dp[i][j]依赖dp[i1][j-1]更短的子串。总结要点说明核心思想从每个中心向两边扩展关键操作奇数中心(i,i)偶数中心(i,i1)时间复杂度O(n²)空间复杂度O(1)

相关新闻

VScode使用uv-创建python虚拟环境

VScode使用uv-创建python虚拟环境

vscode是一个强大的代码编辑器,可以集成许多插件。这里介绍如何在vscode中配置python环境,并运行python脚本。uv是近几年较火的虚拟环境,能很方便的帮助包管理。 1. 安装vscode 在官网中下载安装即可https://code.visualstudio.com/ 2. 安…

2026/10/9 8:01:28 阅读更多 →
自习室预约系统完整工程拆解:微信小程序+Java+MySQL

自习室预约系统完整工程拆解:微信小程序+Java+MySQL

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 8:01:28 阅读更多 →
如何打造无可挑剔的代码品质:从命名到文档的完整检查清单

如何打造无可挑剔的代码品质:从命名到文档的完整检查清单

1. 一个词撬动的品质革命:为什么“impeccable”值得单独拿出来讲第一次看到“impeccable”这个词被单独拎出来当作项目标题,我的反应是:这要么是个极简主义的个人品牌实验,要么是一个对“品质”有执念的人在做一件很较真的事。后来…

2026/10/9 8:00:27 阅读更多 →

最新新闻

KTV聚会点歌辅助工具:基于曲风标签与多人适配的推荐实现

KTV聚会点歌辅助工具:基于曲风标签与多人适配的推荐实现

每次组织K歌聚会,最头疼的不是订包厢,大概是谁点什么歌。我做过一个点歌辅助工具,核心就一条:录入好友的喜好曲风,推荐适配歌曲,顺带把演唱难度和原唱标清楚。做这个事的起因很简单——一次十来人的局&…

2026/10/9 8:28:16 阅读更多 →
基于Kubernetes容器编排的CTFd动态题目靶场插件实战

基于Kubernetes容器编排的CTFd动态题目靶场插件实战

简介:面向高校信息安全、云计算、网络工程等专业课程设计与毕业设计场景,这套资源基于 Kubernetes 容器编排实现了 CTFd 动态题目靶场插件,可较好解决赛事场景下动态题目实例快速创建、调度与回收的需求。压缩包共 34 个文件、约 195KB&#…

2026/10/9 8:28:16 阅读更多 →
智慧社区家庭医生预约系统:Java毕业设计部署与改造实战

智慧社区家庭医生预约系统:Java毕业设计部署与改造实战

简介:这是一套基于Java与MySQL的智慧社区家庭医生预约系统毕业设计完整资料包,面向计算机相关专业学生,可用于课题参考、功能设计、代码实现与论文撰写。压缩包内提供项目源代码、毕业论文文档及答辩PPT模板,具备Java环境即可部署…

2026/10/9 8:28:16 阅读更多 →
Agent Skill 开发实战教程:从入门到精通,用 TaoToken 统一 Key 打通调试链路

Agent Skill 开发实战教程:从入门到精通,用 TaoToken 统一 Key 打通调试链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 8:28:16 阅读更多 →
Python易错题精讲:作用域、闭包、lambda与Py2/Py3差异

Python易错题精讲:作用域、闭包、lambda与Py2/Py3差异

1. 变量作用域:LEGB规则与常见的坑1.1 从一道送命题说起:函数内定义变量为何报错先看一道流传甚广的Python入门题:x 1def func():print(x)x 2func()很多新手一看就答:输出1。因为上面定义了x1,函数里打印x&#xff0…

2026/10/9 8:28:16 阅读更多 →
SpringBoot+Vue+MySQL校园求职招聘系统毕设全流程实战解析

SpringBoot+Vue+MySQL校园求职招聘系统毕设全流程实战解析

一个“毕业设计”项目被做成“源码数据库论文部署文档”的整合包,其实对应的是一个非常经典的技术组合:SpringBoot负责后端接口,Vue负责前端页面,MySQL负责数据存储,三者的协作关系可以说是目前Java Web方向毕业生最熟…

2026/10/9 8:27:15 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →