leetcode热题HOT 131. 分割回文串

一、问题描述:

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

示例 1:

输入:s = "aab"

输出:[["a","a","b"],["aa","b"]]

示例 2:

输入:s = "a"

输出:[["a"]]

二、解题思路:

1、思路分析:本题属于分割问题,for循环的暴力解法太耗时了 。考虑另一种暴力解法-回溯。这里可以参考Carl的回溯方法模板:

java 复制代码
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }
    for (选择:本层集合中的元素) {
        处理单个节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

2、思考回溯的几个关键点:

  • 终止条件:从起始点开始分割字符串,如果分割点startindex>= s.length(),说明分割完毕,找到一组解。
  • 在for (int i = l; i < s.length(); i++)循环中,我们定义了起始位置l,那么 [l, i] 就是要截取的子串。
  • 处理节点就是要判断这个子串是不是回文串,如果是回文,就加入path中,path用来记录切割过的回文子串,然后继续分割剩余的子串,起始位置变为i+1。如果不是回文串则continue 跳过,没必要继续分割了。

3、具体步骤:

  • partition 方法:这是主方法,它接收一个字符串作为参数,然后调用 partitions 方法进行递归分割,并最终返回结果列表。
  • partitions 方法:这是递归的核心方法。它通过遍历字符串的所有可能分割点,从当前分割点开始,判断从当前位置到字符串末尾的子串是否为回文串。如果是回文串,则将该子串加入到当前路径中,并继续递归下一个分割点。如果不是回文串,则跳过当前分割点,继续遍历下一个分割点。
  • isPalindrome 方法:这是用于判断子串是否为回文串的辅助方法。通过首尾指针向中间移动的方式进行判断,如果遇到不相等的字符,则返回 false,否则返回 true。

三、代码示例:

java 复制代码
class Solution {
    List<List<String>> result = new ArrayList<>(); // 存储所有分割结果的列表
    LinkedList<String> path = new LinkedList<>(); // 存储当前分割路径的链表

    public List<List<String>> partition(String s) {
        partitions(s, 0); // 调用递归方法进行分割
        return result; // 返回所有分割结果
    }

    // 递归方法,用于分割字符串并找到所有回文子串
    public void partitions(String s, int l) {
        if (l >= s.length()) { // 当分割点超过字符串长度时,将当前路径加入结果列表
            result.add(new ArrayList<>(path));
            return;
        }
        for (int i = l; i < s.length(); i++) { // 遍历字符串的所有可能分割点
            if (isPalindrome(s, l, i)) { // 如果从当前分割点到 i 的子串是回文串
                path.add(s.substring(l, i + 1)); // 将该子串加入当前路径
            } else {
                continue; // 如果不是回文串,则跳过当前分割点,继续向后遍历
            }
            partitions(s, i + 1); // 递归调用,从下一个位置开始继续分割
            path.removeLast(); // 回溯,移除最后一个子串,尝试其他分割点
        }
    }

    // 判断子串是否为回文串的方法
    public boolean isPalindrome(String s, int l, int r) {
        while (l < r) {
            if (s.charAt(l++) != s.charAt(r--)) {
                return false; // 如果左右指针指向的字符不相等,则不是回文串
            }
        }
        return true; // 如果遍历完整个子串都没有发现不相等的情况,则是回文串
    }
}
  • 时间复杂度分析:
    在 partitions 方法中,对于每个字符,都有两种选择:要么作为一个新的分割点,要么继续向后移动。因此,时间复杂度为 O(2^n)。
    在 isPalindrome 方法中,对于每个子串,最坏情况下需要遍历整个子串的长度,时间复杂度为 O(n)。
    综上所述,总的时间复杂度为 O(n * 2^n)。

四、总结与补充:

1、判断回文子串:字符串反转后和原字符串相同即为回文串,可用双指针法判断。

java 复制代码
    private boolean huiwen(String s, int startIndex, int end) {
        for (int i = startIndex, j = end; i < j; i++, j--) {
            if (s.charAt(i) != s.charAt(j)) return false;
        }
        return true;

2、字符串截取:通过subString()方法来进行字符串截取,返回字符串中的子字符串。

①传递一个参数:

java 复制代码
public String substring(int beginIndex);

子字符串从指定索引处的字符开始,到此字符串末尾。

②传递两个参数:

java 复制代码
public String substring(int beginIndex, int endIndex);

从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符。因此,该子字符串的长度为 endIndex-beginIndex。

参数说明:beginIndex -- 起始索引(包括)、endIndex -- 结束索引(不包括)。

相关推荐
diudiu96289 分钟前
Maven配置阿里云镜像
java·spring·阿里云·servlet·eclipse·tomcat·maven
Yeats_Liao15 分钟前
MindSpore开发之路(四):核心数据结构Tensor
数据结构·人工智能·机器学习
魔芋红茶21 分钟前
Netty 简易指南
java·开发语言·netty
fab 在逃TDPIE27 分钟前
Sentaurus TCAD 仿真教程(十)
算法
大学生资源网40 分钟前
基于springboot的万亩助农网站的设计与实现源代码(源码+文档)
java·spring boot·后端·mysql·毕业设计·源码
小严家42 分钟前
Java基础教程大全完整学习路径
java·开发语言·学习
毕设源码-朱学姐42 分钟前
【开题答辩全过程】以 基于Java的电影推荐系统为例,包含答辩的问题和答案
java·开发语言
天赐学c语言1 小时前
12.19 - 买卖股票的最佳时机 && const的作用
c++·算法·leecode
sheji34161 小时前
【开题答辩全过程】以 基于SSM的校园新冠疫苗接种信息管理系统为例,包含答辩的问题和答案
java·开发语言
菜鸟233号1 小时前
力扣78 子集 java实现
java·数据结构·算法·leetcode