当前位置: 首页 > news >正文

131. 分割回文串

131. 分割回文串

中等

给你一个字符串s,请你将s分割成一些 子串,使每个子串都是回文串。返回s所有可能的分割方案。

示例 1:

输入:s = "aab" 输出:[["a","a","b"],["aa","b"]]

示例 2:

输入:s = "a" 输出:[["a"]]

提示:

  • 1 <= s.length <= 16
  • s仅由小写英文字母组成

📝 核心笔记:分割回文串 (选或不选 / 逗号切割法)

1. 核心思想 (一句话总结)

“手拿菜刀走到底:每个字符后面,切一刀还是连着走?”

我们遍历字符串的每一个字符索引 i,对于 i 和 i+1 之间的缝隙,我们面临两个选择:

  1. 不切 (Join):当前子串还没结束,继续往后看下一位。
  2. 切 (Cut):当前子串[start, i]结束。前提是:切下来的这段必须是回文串。

💡图像记忆 (切香肠):

  • 你有一根香肠aab
  • 走到第一个a后面:
    • 不切:等着凑个更大的(比如aa)。
    • :切下来一块a(它是回文,合法),然后处理剩下那截。
2. 算法流程 (Input View)

这也是典型的选或不选模型(Binary Tree):

  1. Base Casei == n,说明整个字符串处理完了,收集结果。
  2. 分支一:不切 (Skip)
    • 条件:i < n - 1。因为最后一个字符后面必须完结(不能悬在半空),所以只有不是最后一个字符时,才能选择“不切”。
    • 动作:dfs(i + 1, start)start不变,子串变长了。
  1. 分支二:切 (Pick)
    • 条件:isPalindrome(start, i)。只有当前是回文才能切。
    • 动作:记录子串,dfs(i + 1, i + 1)。下一个子串从i+1开始。
    • 回溯removeLast
🔍 代码回忆清单 (带注释版)
// 题目:LC 131. Palindrome Partitioning class Solution { public List<List<String>> partition(String s) { List<List<String>> ans = new ArrayList<>(); List<String> path = new ArrayList<>(); dfs(0, 0, s, path, ans); return ans; } // i: 当前正在考虑第 i 个字符 (作为潜在的结尾) // start: 当前子串的起始位置 private void dfs(int i, int start, String s, List<String> path, List<List<String>> ans) { // 1. Base Case: 走到字符串末尾 if (i == s.length()) { ans.add(new ArrayList<>(path)); // 复制结果 return; } // 2. 分支 A: 不切 (Don't Split) // 只有不到最后一位时,才能选择"不切"继续连 // 如果到了最后一位(n-1),必须切,否则字符串就没结束 if (i < s.length() - 1) { // i 往前移,但 start 不动 (子串在变长) dfs(i + 1, start, s, path, ans); } // 3. 分支 B: 切 (Split) // 只有 [start, i] 是回文串时,才有资格切这一刀 if (isPalindrome(s, start, i)) { path.add(s.substring(start, i + 1)); // i 往前移,start 也移到 i+1 (新子串的起点) dfs(i + 1, i + 1, s, path, ans); path.removeLast(); // 回溯 } } // 标准双指针判断回文 private boolean isPalindrome(String s, int left, int right) { while (left < right) { if (s.charAt(left++) != s.charAt(right--)) { return false; } } return true; } }
⚡ 快速复习 CheckList (易错点)
  • [ ]对比标准解法 (For循环枚举)?
    • 你的解法 (二叉树):每个缝隙选/不选。递归深度 。
    • 标准解法 (N叉树):站在start,枚举终点j(从startn)。
    • 结论:你的解法逻辑严密,但在 Java 中因为substring的存在,效率相差不大。面试中两种皆可,标准解法代码略短一些。
  • [ ]边界条件i < n - 1
    • 这是此解法的命门
    • 如果i到了最后一个字符,你不能选择“不切”,因为那样会导致递归结束时,最后一段substring没被加入path,字符串被“吞”了一截。
  • [ ]回文判断优化?
    • 目前isPalindrome是 。整个算法接近 。
    • 如果字符串很长,可以用动态规划 (DP)预处理一个boolean[][] isPal表,把判断降为 。
🖼️ 数字演练

输入s = "aab"

  1. DFS(0, 0): 指针在第一个 'a'。
    • 不切:DFS(1, 0)-> start=0, i=1 (当前看着 "aa")。
    • : "a" 是回文 ->path=["a"]->DFS(1, 1)
  1. 分支:DFS(1, 0)(刚才选择了不切,现在看第二个 'a')
    • 不切:DFS(2, 0)-> start=0, i=2 (当前看着 "aab")。
    • : "aa" 是回文 ->path=["aa"]->DFS(2, 2)-> 剩下 "b" -> ... ->["aa", "b"]
  1. 分支:DFS(1, 1)(刚才切了第一个 'a',start=1)
    • 不切:DFS(2, 1)-> start=1, i=2 (当前看着 "ab")。
    • : "a" 是回文 ->path=["a", "a"]->DFS(2, 2)-> ... ->["a", "a", "b"]

(最终结果:["aa", "b"], ["a", "a", "b"])

http://www.jsqmd.com/news/409998/

相关文章:

  • [特殊字符] CUDA内核功耗波动:测试从业者的性能与能效攻防战
  • 拒绝报价乱象|BH健身房器材报价透明指南,上海杰禾力带你明明白白消费 - 冠顶工业设备
  • 漏洞防御革命:Renovate如何斩断供应链攻击链条?
  • 题解:AcWing 900 整数划分
  • C#中 Invoke、begininvoke、InvokeRequired的详细讲解和三者之间的区别
  • 探寻江西新华电脑学院线上报名入口,人工智能专业特色与教师责任心情况 - 工业品牌热点
  • 基于JSP的高校财务处理系统的设计与实现(11895)
  • AT_arc183_c [ARC183C] Not Argmax
  • C# 的开闭原则(OCP)在工控上位机开发中的具体应用
  • 2026年高性价比便携式打印机制造商排名,广州小篆科技值得关注 - 工业推荐榜
  • C#中的反射是什么?详细讲解以及在工控上位机中如何应用
  • 细聊颜语堂英语四六级课程费用,报名流程复杂吗学员评价好吗? - mypinpai
  • CatBoost 高级 API 深度解析:超越默认参数的实战技巧与设计哲学
  • vCenter Server 8.0U3i 新增功能简介
  • 深度测评做品牌咨询的公司哪家专业:全案能力+落地深度(防坑指南) - 品牌排行榜
  • 求职必看:纽约的数据分析岗位在哪里投递申请?(高效渠道盘点) - 品牌排行榜
  • 题解:AcWing 282 石子合并
  • 深度测评满意度调研网站哪个好用:头部机构对比(指南) - 品牌排行榜
  • 江苏有哪些专业做运动仿真服务的公司?2026全新原创选型指南 - 冠顶工业设备
  • 浑身肌肉酸痛吃保健品哪个品牌好?专业品牌测评(防坑指南) - 品牌排行榜
  • ESXi 8.0U3i 新增功能简介
  • 题解:AcWing 898 数字三角形
  • 题解:AcWing 899 编辑距离
  • zerofs 支更多兼容s3服务了
  • 十家品牌全案公司推荐:大定位理论+年度全案陪跑(避坑攻略) - 品牌排行榜
  • JAVA面试题速记-mysql基础
  • 题解:AcWing 5 多重背包问题 II
  • 题解:AcWing 9 分组背包问题
  • 题解:AcWing 4 多重背包问题 I
  • 莱博雷生Lemborexant治疗失眠症的标准睡前给药方案与次日嗜睡风险评估