组合与括号生成(回溯)

本篇基于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

相关推荐
网络风云38 分钟前
Flask(补充内容)配置SSL 证书 实现 HTTPS 服务
python·https·flask·ssl
槐月杰3 小时前
C语言中冒泡排序和快速排序的区别
c语言·算法·排序算法
暴力袋鼠哥5 小时前
基于YOLO11的车牌识别分析系统
python
笺上山河梦5 小时前
文件操作(二进制文件)
开发语言·c++·学习·算法
大慕慕好懒5 小时前
PHP弱类型hash比较缺陷
算法·哈希算法
snowfoootball6 小时前
最短路问题
数据结构·算法
有你的冬天1987 小时前
数据结构(一)
数据结构·算法
满怀10157 小时前
【Python进阶】列表:全面解析与实战指南
python·算法
爱学习的uu7 小时前
决策树:ID3,C4.5,CART树总结
算法·决策树·机器学习
wuqingshun3141598 小时前
蓝桥杯 9. 九宫幻方
数据结构·c++·算法·职场和发展·蓝桥杯·深度优先