组合型回溯+剪枝
本篇基于b站灵茶山艾府。
77. 组合
给定两个整数 n 和 k,返回范围 [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]]
class Solution: def combine(self, n: int, k: int) -> List[List[int]]: # 与子集型组合唯一的区别在于path数组长度是确定的 # dfs(i)表示在下标小于等于i的数组中选择k个数的组合 # 1.选或不选 # def dfs(i): # nonlocal k # if k == 0: # 已经选完了k个数,不用再继续递归 # ans.append(path.copy()) # return # if i == 0: # return # dfs(i - 1) # k -= 1 # path.append(i) # dfs(i - 1) # path.pop() # k += 1 # 2.枚举选哪个数 def dfs(i): nonlocal k if k == 0: ans.append(path.copy()) for j in range(i, 0, -1): k -= 1 path.append(j) dfs(j - 1) path.pop() k += 1 path = [] ans = [] dfs(n) return ans
216. 组合总和 III
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
- 只使用数字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,没有有效的组合。
class Solution: def combinationSum3(self, k: int, n: int) -> List[List[int]]: # dfs(i)表示从[1,i]中选择相加之和为n的k个数的集合 # 1.选/不选 # def dfs(i): # nonlocal k, n # # 剪枝,如果最大的k个数不能构成n,那么后面怎么递归都无法得出答案 # if i >= k and n > (i + i - k + 1) * k // 2: # return # if k == 0 and n == 0: # ans.append(path.copy()) # return # if i == 0: # return # dfs(i - 1) # 不选当前数字 # k -= 1 # n -= i # path.append(i) # dfs(i - 1) # path.pop() # n += i # k += 1 # 2.枚举选哪个数字 def dfs(i): nonlocal k, n if i >= k and n > (i + i - k + 1) * k // 2: return if n == 0 and k == 0: ans.append(path.copy()) return for j in range(i, 0, -1): k -= 1 n -= j path.append(j) dfs(j - 1) n += j k += 1 path.pop() path = [] ans = [] dfs(9) return ans
22. 括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1 输出:["()"]
class Solution: def generateParenthesis(self, n: int) -> List[str]: # def(i)表示在下标大于等于i的位置中生成所有可能的有效括号组合 # 什么时候可以放左括号? # 只要左括号个数小于n,都可以放 # 什么时候可以放右括号? # 已经放的右括号个数小于左括号个数时,就可以放 def dfs(i): nonlocal left, right if i == n * 2: ans.append("".join(path)) if left
(图片来源网络,侵删)(图片来源网络,侵删)(图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。