python-leetcode 60.分割回文串

发布于:2025-03-21 ⋅ 阅读:(13) ⋅ 点赞:(0)

题目:

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


方法一:回溯+深度优先搜索

1. 主要思想
  • 使用 深度优先搜索(DFS) 遍历 s 的所有可能划分方式。
  • 使用 回溯(Backtracking)尝试所有可能的子串分割,并在搜索失败时撤销上一步决策。
  • 剪枝优化:如果某个子串不是回文,就直接跳过,减少不必要的递归调用。

"aab" 为例,我们一步步拆解执行过程:

(1) 递归函数 dfs(i)
  • dfs(i) 代表从索引 i 开始尝试分割 s[i:]
  • 终止条件:当 i == n(遍历完整个字符串),说明找到了一个完整的回文划分,将 path 复制到 ans 中。
(2) 遍历所有可能的子串
  • j 为子串 s[i:j+1] 的结束索引:
    • 如果 s[i:j+1]回文,则递归处理 s[j+1:]
    • 如果 s[i:j+1] 不是回文,就跳过这个分割。
Step 1: dfs(0)
  • i = 0,遍历 j02
    1. s[0:1] = "a" 是回文 → 加入 pathdfs(1)
    2. s[0:2] = "aa" 是回文 → 加入 pathdfs(2)
    3. s[0:3] = "aab" 不是回文 → 跳过
Step 2: dfs(1)(继续从 "a" 后开始)
  • i = 1,遍历 j12
    1. s[1:2] = "a" 是回文 → 加入 pathdfs(2)
Step 3: dfs(2)(继续从 "a" 后开始)
  • i = 2,遍历 j22
    1. s[2:3] = "b" 是回文 → 加入 pathdfs(3)
Step 4: dfs(3)(终止条件)
  • i = 3 == len(s),找到一个完整的划分 ["a", "a", "b"],存入 ans,然后回溯。

4. 回溯过程

  • 回溯到 dfs(2),撤销 "b",继续找其他可能(没有)。
  • 回溯到 dfs(1),撤销 "a",尝试 "aa"
    • "aa" 是回文 → dfs(2)
    • 继续拆分 s[2:3] = "b",得到 ["aa", "b"],存入 ans

最终 ans = [["a", "a", "b"], ["aa", "b"]]

class Solution(object):
    def partition(self, s):
        """
        :type s: str
        :rtype: List[List[str]]
        """
        n=len(s)  #字符串的长度
        ans=[]   #存储所有符合条件的回文子串分割方案
        path=[]  #存储当前的分割方案,DFS过程中会不断更新
        def dfs(i):
            if i==n:  #被分割完毕
                ans.append(path[:])  #复制
                return 
            for j in range(i,n):
                t=s[i:j+1]  #t是s的子串,索引 i 到 j
                if t==t[::-1]:  #生成t的逆序,判断是否为回文
                    path.append(t)#将 t 加入当前分割方案
                    dfs(j+1)# 递归处理s[j+1:]
                    path.pop() #回溯
        dfs(0)
        return ans

时间复杂度:O(n2n),其中 n 为 s 的长度

空间复杂度:O(n)