组合与括号生成(回溯)

本篇基于b站灵茶山艾府

77. 组合

给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例 1:

复制代码
输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

示例 2:

复制代码
输入:n = 1, k = 1
输出:[[1]]

python 复制代码
class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        ans = []
        path = []

        # 1.方法1:每个节点有选/不选分支,在叶子节点处收割结果
        # def dfs(i):
        #     if i > n:
        #         if len(path) == k:
        #             ans.append(path.copy())
        #         return
        #     dfs(i + 1)
        #     path.append(i)
        #     dfs(i + 1)
        #     path.pop()

        # dfs(1)
        # return ans

        # 2.方法2:没有不选的分支,必须选后面的一个元素,且在每个节点处收割结果
        def dfs(i):
            d = k - len(path)  # 代表还需要d个数
            if i < d:
                return  # 剪枝,代表下面继续递归也没法找出d个数存进path数组了
            if len(path) == k:
                ans.append(path.copy())
                return  # 必须return,不然path数组长度会大于k不满足条件

            for j in range(i, 0, -1):  # 倒序
                path.append(j)
                dfs(j - 1)
                path.pop()  # 回溯

        dfs(n)
        return ans

216. 组合总和 III

找出所有相加之和为 nk 个数的组合,且满足下列条件:

  • 只使用数字1到9
  • 每个数字 最多使用一次

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

示例 1:

复制代码
输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。

示例 2:

复制代码
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。

示例 3:

复制代码
输入: k = 4, n = 1
输出: []
解释: 不存在有效的组合。
在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。

python 复制代码
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        ans = []
        path = []

        # 方法1:选/不选思路,到叶子节点处收割结果
        # def dfs(i):
        #     if sum(path) > n or len(path) > k:
        #         return  # 剪枝
        #     if i > 9:
        #         if sum(path) == n and len(path) == k:
        #             ans.append(path.copy())
        #         return
        #     dfs(i + 1)
        #     path.append(i)
        #     dfs(i + 1)
        #     path.pop()

        # dfs(1)
        # return ans

        # 方法2:必须选一个后面的数,每个节点处收割结果
        def dfs(i):
            d = k - len(path)
            if i < d:  # 剪枝
                return

            if len(path) == k and sum(path) == n:
                ans.append(path.copy())
                return

            for j in range(i, 0, -1):
                path.append(j)
                dfs(j - 1)
                path.pop()

        dfs(9)
        return ans

22. 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

复制代码
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

复制代码
输入:n = 1
输出:["()"]

python 复制代码
class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        # 每个字符的前缀中左括号的个数必须大于等于右括号,且左括号和右括号的总个数都是n
        # 用选/不选的思路,选的时候就放左括号,不选就放右括号
        # ans = []
        # path = [""] * 2 * n

        # def dfs(i, left):
        #     if i == 2 * n:
        #         ans.append("".join(path))
        #         return
        #     # 如果左括号个数小于n,则可以放左括号
        #     if left < n:
        #         path[i] = "("
        #         dfs(i + 1, left + 1)

        #     # 如果右括号个数小于左括号,则可以放右括号
        #     if i - left < left:
        #         path[i] = ")"
        #         dfs(i + 1, left)

        # dfs(0, 0)
        # return ans

        # 上面不用pop回溯的原因是每次右括号已经把左括号的值覆盖了
        # 若一开始不设置path数组大小,每次都append进去括号,就要pop回溯
        ans = []
        path = []

        def dfs(i, left):
            if i == 2 * n:
                ans.append("".join(path))
                return
            # 如果左括号个数小于n,则可以放左括号
            if left < n:
                path.append("(")
                dfs(i + 1, left + 1)
                path.pop()

            # 如果右括号个数小于左括号,则可以放右括号
            if i - left < left:
                path.append(")")
                dfs(i + 1, left)
                path.pop()

        dfs(0, 0)
        return ans

相关推荐
橘和柠1 小时前
知识图谱实战(一):数据采集与实体关系抽取(完整代码)
算法
用户7088769039381 小时前
给传统 SaaS 增加 AI 能力:3个真实落地场景
python
卷无止境1 小时前
FastAPI中间件全解析:请求处理链条上的隐形关卡
后端·python·fastapi
用户0332126663671 小时前
使用 Python 将 HTML 内容添加到 PowerPoint 演示文稿中
python·html
看浪的路人2 小时前
第4讲:MCP Client 开发——连接、发现、调用
windows·python·ai
Mem0rin2 小时前
前缀和:中心下标与数组乘积
数据结构·算法
windliang2 小时前
Claude Code 源码分析(八):Memory 如何被写入、整理与按需召回
前端·算法·面试
Swift社区2 小时前
Python 开发环境怎么选?PyCharm、VS Code、Trae 谁更适合 AI 开发?
人工智能·python·pycharm
漂流瓶jz2 小时前
UVA-12174 Shuffle的播放记录 题解答案代码 算法竞赛入门经典第二版
数据结构·c++·算法·图论·滑动窗口·算法竞赛入门经典·uva
卷无止境2 小时前
聊聊Web开发里的流式数据 从原理到FastAPI实战
后端·python·fastapi