Leetcode 分割回文串

算法思想

1. 回溯法 (Backtracking):

  • 回溯法是一种通过递归去尝试所有可能的解,并在每次递归中做出选择、回溯的策略。
  • 在这道题中,我们需要通过回溯法来生成字符串的所有可能分割方式,并判断每个分割的子串是否为回文。

2. 分割与判断:

  • 首先,我们从字符串的第一个字符开始,依次检查从第一个字符到当前字符构成的子串是否为回文。
  • 如果当前子串是回文串,就可以继续尝试从这个子串的结尾位置向后继续分割剩下的部分。
  • 如果遍历完所有字符并且成功将字符串分割为回文子串(即字符串遍历完时,所有分割都是回文),就将这种分割方案保存起来。

3. 递归与回溯:

  • backtrack 方法是递归函数,用来从当前字符开始向后尝试不同的分割方法。
  • 每次找到一个回文串后,将其加入当前的结果列表 (currentList),然后递归处理剩下的部分。
  • 当递归到字符串结尾(即 start == s.length()),说明找到了一种合法的分割方式,这时将当前的分割方式保存到最终结果 result 中。
  • 当回溯返回时,撤销之前的选择,即将最后加入的回文串从列表中移除 (currentList.remove(currentList.size() - 1)),从而继续寻找其他可能的分割方案。

4. 判断回文串:

  • isPalindrome 方法中,通过双指针(从字符串两端向中间遍历)来判断某个子串是否是回文。
  • 只要发现左右两端字符不相等,就可以确定该子串不是回文,立即返回 false,否则继续判断直到中间。

代码执行过程(以 "aab" 为例):

  • 输入字符串 s = "aab"
  • 第一次递归从第一个字符开始,先检查子串 "a" 是否为回文,发现是回文,于是将 "a" 放入当前的分割列表,然后递归处理剩下的子串 "ab"
  • 在处理 "ab" 时,首先检查 "a",也是回文,于是继续递归处理 "b"。发现 "b" 也是回文,递归结束,得到一种分割方案 ["a", "a", "b"]
  • 回溯后,移除最后的 "b",然后继续尝试检查 "ab",发现不是回文,无法进行分割。
  • 继续回溯到最外层,移除 "a",然后尝试检查前两个字符 "aa",发现是回文,于是递归处理剩下的 "b",得到另一种分割方案 ["aa", "b"]
  • 递归结束,最终返回所有的分割结果。

复杂度分析:

  • 时间复杂度: 最坏情况下,每个子串都可能是回文,所以需要遍历所有可能的分割方式,时间复杂度大致为 O(n * 2^n),其中 n 是字符串的长度。
  • 空间复杂度: 由于递归深度取决于字符串的长度,因此空间复杂度为 O(n)。

总结:

这个算法通过回溯法,递归地生成所有可能的子串分割,并通过逐个判断子串是否为回文来过滤合法的分割方案。

java solution

java 复制代码
class Solution {
    public List<List<String>> partition(String s) {
        //result包含所有可能的回文分割方案
        List<List<String>> result = new ArrayList<>();
        //currentList代表某一种可能的回文分割方案
        List<String> currentList = new ArrayList<>();
        backtrack(result, currentList, s, 0);
        return result;
    }
    private void backtrack(List<List<String>> result, List<String> currentList, String s, int start) {
        if(start == s.length()) {
            result.add(new ArrayList<>(currentList));
            return; //这里必须return,递归终止条件
        }
        for(int i = start; i < s.length(); ++i) {
            if(isPalindrome(s, start, i)) {
                currentList.add(s.substring(start, i + 1)); //添加了一个回文子串,currentList.size()增加1
                backtrack(result, currentList, s, i + 1);
                currentList.remove(currentList.size() - 1); //撤销上个回文子串的选择
            }
        }

    }
    private boolean isPalindrome(String s, int low, int high) {
        while(low < high) {
            if(s.charAt(low) != s.charAt(high)) {
                return false;
            }
            low++;//注意更新左右指针!!
            high--;
        }
        return true;
    }
}
相关推荐
有梦想的小何11 小时前
Cursor AI 编程实战(篇一):Prompt 与案例总结
java·linux·prompt·ai编程
@我漫长的孤独流浪11 小时前
计算机系统核心概念与性能优化全解析
算法·计算机外设
程序 代码狂人11 小时前
Linux查询自己环境的一些基础命令
linux·运维·服务器
如竟没有火炬11 小时前
接雨水22
数据结构·python·算法·leetcode·散列表
ʚ希希ɞ ྀ11 小时前
二叉树的锯齿层序遍历
数据结构·算法
进击切图仔11 小时前
RAG 加载 pdf 文档
linux·前端·pdf
aerror11 小时前
如何使用ubuntu搭建一个无盘PC启动服务器
linux·服务器·ubuntu
SWAGGY..11 小时前
Linux系统编程:(五)基础开发工具:vim编辑器的使用及其配置操作
linux·编辑器·vim
澈20711 小时前
二叉搜索树:高效增删查的秘诀
java·开发语言·算法
无敌昊哥战神11 小时前
大模型(LLM)推理优化技术全景总结
python·算法·大模型