[面试精选] 0131. 分割回文串

题目链接


131. 分割回文串 - 力扣(LeetCode)


题目描述


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

题目示例


示例 1 :

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

示例 2 :

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

解题思路


  1. 问题描述
    给定一个字符串,要求将其分割成若干子串,使得每个子串都是回文。返回所有可能的分割方案。
  2. 核心思路
    • 深度优先搜索(DFS):通过递归遍历所有可能的分割点。
    • 回溯:在找到一个有效的回文子串后,将其加入当前路径,并继续搜索剩余部分;搜索完成后回溯,尝试其他分割方式。
    • 回文判断:检查子串是否是回文,只有回文子串才能被加入路径。
  3. 关键步骤
    • 从字符串的第一个字符开始,逐步向后遍历。
    • 对于每个位置,检查从起始点到当前位置的子串是否是回文。
    • 如果是回文,将其加入路径,并递归处理剩余字符串。
    • 回溯时移除最后加入的子串,尝试其他分割方式。
    • 当遍历到字符串末尾时,将当前路径加入结果集。

题解代码


class Solution {
    // 存储所有可能的分割方案
    private final List<List<String>> ans = new ArrayList<>();
    // 存储当前的分割路径
    private final List<String> path = new ArrayList<>();
    // 原始字符串
    private String s;

    public List<List<String>> partition(String s) {
        this.s = s;
        // 从字符串的第一个字符开始深度优先搜索
        dfs(0, 0);
        return ans;
    }

    private void dfs(int i, int start) {
        // 如果已经遍历到字符串末尾,将当前路径加入结果集
        if (i == s.length()) {
            ans.add(new ArrayList<>(path));
            return;
        }

        // 如果未到字符串末尾,尝试不分割当前字符,继续向后遍历
        if (i < s.length() - 1) {
            dfs(i + 1, start);
        }

        // 检查从start到i的子串是否是回文
        if (isPalindrome(start, i)) {
            // 如果是回文,将该子串加入当前路径
            path.add(s.substring(start, i + 1));
            // 从下一个字符开始新的分割
            dfs(i + 1, i + 1);
            // 回溯,移除最后加入的子串
            path.removeLast();
        }
    }

    // 判断子串是否是回文
    private boolean isPalindrome(int left, int right) {
        while (left < right) {
            if (s.charAt(left++) != s.charAt(right--)) {
                return false;
            }
        }
        return true;
    }
}


复杂度分析


  1. 时间复杂度
    • 最坏情况下,字符串的所有可能分割方式为O(2^N)N为字符串长度),因为每个字符都可以选择分割或不分割。
    • 每次分割需要检查回文,时间复杂度为O(N)
    • 总时间复杂度为:O(N * 2^N)
  2. 空间复杂度
    • 递归调用栈的最大深度为N,因此空间复杂度为:O(N)(不考虑结果集的空间占用)。
    • 结果集的空间复杂度为O(2^N),因为最多可能有2^N种分割方案。
    • 总空间复杂度为:O(N + 2^N)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值