力扣131-分割回文串

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

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

示例 1:

输入: s = "aab"

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

示例 2:

输入: s = "a"

**输出:[["a"]]

提示:

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

如果已经在某个位置切了一刀,那么接着只需要考虑这个位置后面的子串怎么切,这就有点"问题与子问题"的意思在了,可以写一个 dfs 函数,dfs(i) 表示字符串 s 未分割的部分是从下标 i 开始到字符串末尾,那么递归终止条件是 i == n

接着再看[i, n - 1]这部分子串,要在哪切?显然必须要从 i 开始往后枚举每个位置,看看这个位置 j 能否与起点 i 构成回文串。如果不行就继续往后枚举;如果可以,那么就将这个回文串加入答案,然后从 j + 1 开始往后找回文串,也就是调用 dfs(j + 1),dfs(j + 1) 返回后,把本次加入答案的结果弹出(因为一直递归调用 dfs 必然能走到 i == n 的时候,此时 path 会被加入到 ans 中),然后继续循环

也就是说,dfs 递归调用控制的是切几刀,递归深度越深,切的刀数就越多,因为一直在前面已经切了的基础上往后切。遍历控制的是在哪切,在当前刀数一定的情况下,往后找分割的位置

python 复制代码
from typing import List

def partition(s: str) -> List[List[str]]:
    ans = []
    path = []
    n = len(s)

    def dfs(i: int) -> None:
        # dfs(i) 表示 s 未分割的部分为 [i,n - 1]
        if i == n:
            # 不能用 ans.append("".join(path)),否则无法 pop
            ans.append(path.copy())
            return
        # 枚举终点
        for j in range(i, n):
            substr = s[i: j + 1] # 把子串分割出来
            if substr == substr[::-1]:
                # 如果是回文串
                path.append(substr)
                dfs(j + 1) # 从当前回文串的终点的后一个位置开始往后找新的串
                path.pop() # 恢复现场
    dfs(0)
    return ans

def main():
    with open("case.txt", "r") as f:
        ss = f.read().split()

    for s in ss:
        result = partition(s)
        print(f"s = {s}")
        print(result)
        print()

if __name__ == "__main__":
    main()
相关推荐
Bmob后端云22 分钟前
Bmob后端云实战|Python给备忘录接入AI摘要、文本润色功能
算法·github
小鱼干..33 分钟前
CTFHub技能树-ssrf-URL Bypass
算法
chushiyunen1 小时前
动态规划、贪心算法、分治法
算法·贪心算法·动态规划
hansang_IR1 小时前
【题解】P4456 [CQOI2018] 交错序列(数学递推)
c++·算法
青少儿编程课堂1 小时前
贪心算法进阶:区间调度与最少资源整合解析
c++·python·算法·贪心·信息学竞赛·区间调度
青山木1 小时前
Hot 100 --- 划分字母区间
java·数据结构·算法·leetcode·贪心算法
Sunsets_Red2 小时前
浅谈扫描线
c++·算法·编程·题解·洛谷·扫描线·信息学竞赛
a187927218312 小时前
【算法】双指针与滑动窗口(一):框架总纲——三类问题、一个原理与判决书
算法·leetcode·区间·双指针·滑动窗口·原理·算法讲解
shehuiyuelaiyuehao2 小时前
算法42,模拟算法,模拟z字形变换
算法
朝朝辞暮i2 小时前
C++第一课
开发语言·c++·算法