LeetCode 热题 100 131. 分割回文串

发布于:2025-05-09 ⋅ 阅读:(15) ⋅ 点赞:(0)

LeetCode 热题 100 | 131. 分割回文串

大家好,今天我们来解决一道经典的回溯算法问题——分割回文串。这道题在 LeetCode 上被标记为中等难度,要求将一个字符串 s 分割成若干个子串,使得每个子串都是回文串,并返回所有可能的分割方案。


问题描述

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

示例 1:

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

示例 2:

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

提示:

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

解题思路

核心思想
  1. 回溯法

    • 使用回溯法(Backtracking)来解决这个问题。
    • 从字符串的起始位置开始,尝试所有可能的分割点,检查每个子串是否为回文串。
    • 如果当前子串是回文串,则将其加入当前路径,并继续处理剩余部分。
    • 如果到达字符串的末尾,则将当前路径加入结果列表。
  2. 辅助函数

    • 使用一个辅助函数 is_palindrome 来判断一个子串是否为回文串。
  3. 回溯过程

    • 使用一个递归函数 backtrack,记录当前路径和处理到的位置。
    • 在每次递归调用中,尝试所有可能的分割点,如果当前子串是回文串,则继续递归处理剩余部分。

Python代码实现

class Solution:
    def partition(self, s: str) -> List[List[str]]:
        def is_palindrome(sub):
            return sub == sub[::-1]
        
        def backtrack(start, path):
            if start == len(s):
                result.append(path[:])
                return
            for end in range(start + 1, len(s) + 1):
                if is_palindrome(s[start:end]):
                    path.append(s[start:end])
                    backtrack(end, path)
                    path.pop()
        
        result = []
        backtrack(0, [])
        return result

代码解析

  1. 辅助函数

    • is_palindrome(sub):判断子串 sub 是否为回文串。
    • 使用字符串反转的方法 sub == sub[::-1] 来判断。
  2. 回溯函数

    • backtrack(start, path):从位置 start 开始,尝试所有可能的分割点。
    • 如果到达字符串的末尾(start == len(s)),将当前路径 path 加入结果列表 result
    • 对于每个可能的分割点 end,检查子串 s[start:end] 是否为回文串。
    • 如果是回文串,则将其加入当前路径 path,并递归处理剩余部分。
    • 递归返回后,从路径中移除最后一个子串(回溯)。
  3. 主函数

    • 初始化结果列表 result
    • 调用 backtrack(0, []),从字符串的起始位置开始处理。

复杂度分析

  • 时间复杂度:O(2^n * n),其中 n 是字符串 s 的长度。最坏情况下,每个位置都可能是一个分割点,需要尝试所有可能的分割方案。
  • 空间复杂度:O(n),递归调用栈的深度最多为字符串的长度。

示例运行

示例 1
输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例 2
输入:s = "a"
输出:[["a"]]

总结

通过回溯法,我们可以高效地解决分割回文串问题。回溯法的核心在于尝试所有可能的分割点,并通过辅助函数判断子串是否为回文串。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!

关注我,获取更多算法题解和编程技巧!


网站公告

今日签到

点亮在社区的每一天
去签到