给你一个 无重复元素 的整数数组 candidates
和一个目标整数 target
,找出 candidates
中可以使数字和为目标数 target
的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates
中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target
的不同组合数少于 150
个。
输入:candidates =[2,3,6,7]
, target =7
输出:[[2,2,3],[7]]
可以看出 元素是可以重复选的 那么return 条件就是相加等于target 就存储到列表数组中 但是结果是顺序无关的 那么就是组合
我们来先试着写一下代码
class Solution(object): def combinationSum(self, candidates, target): res = [] def backtrack(path): if sum(path) == target: # 检查当前路径的和 res.append(path.copy()) # 记录合法组合 return #剪枝条件就是只有和小于target的时候 才可以继续往下 if sum(path)<target: for i in candidates: path.append(i) backtrack(path) path.pop()#回溯 backtrack([]) return res solution=Solution() result=solution.combinationSum([2,3,6,7],7) print(result)
这个是我第一遍写的代码 我的思路很简单 就是在path之和等于target的时候return 要想继续进行下去 path之和必须小于target才行 如果小于 那么就在这个candidates中选择 因为可以重复选择 将i加上去 然后递归 如果等于那么就return 之后将这个加上去的元素pop 尝试其他新的元素 如果不小于 那这个枝条就被剪掉了 如果小于 就继续执行 (建议是将最简单的全排列看懂 其他的就按照这个模式来写 不然会觉得心里乱糟糟的)
然后输出结果是这样的:[[2, 2, 3], [2, 3, 2], [3, 2, 2], [7]]
很明显 重复了 因为要按照一个组合来看 而不是一个排列 排列的话顺序不同也会是不同的结果 但是组合的话是不管顺序的
class Solution(object): def combinationSum(self, candidates, target): res = [] def backtrack(start,path): if sum(path) == target: # 检查当前路径的和 res.append(path.copy()) # 记录合法组合 return #剪枝条件就是只有和小于target的时候 才可以继续往下 if sum(path)<target: for i in range(start,len(candidates)):#start从0开始 path.append(candidates[i]) backtrack(i+1,path)#我这个代码的意思就是不能重复选或者回去选 就直接是i+1 这样的结果就会导致不符合题目的可以选择重复元素 path.pop()#回溯 backtrack(0,[]) return res solution=Solution() result=solution.combinationSum([2,3,6,7],7) print(result)
看一下我这个代码的修改 这个代码的意思就是不会重复选 也不会再回头选 这样就会导致结果里面是没有重复的情况的 但是也会导致有些元素不能重复选 这个的打印结果是只有7这一个数组
但是我们想要的是不要回过去选 但是可以重复选 所以backtrack就可以使(i,path)这样就可以重复选择元素 传递 i
(而不是 i+1
)到下一层递归,使得当前元素 candidates[i]
可以被重复选择。 外层的 for i in range(start, len(candidates))
保证了只会从 start
开始向后选,不会扫描 candidates[0..start-1]
的元素,因此不会回头选。
每次循环 i
从 start
递增,确保:
- 同一层递归:尝试选择
candidates[start]
,candidates[start+1]
, ... - 下一层递归:通过
backtrack(i, path)
决定是否重复选当前元素或推进到下一个。 - 避免重复组合:
即使允许重复选i
,for
循环的逐步推进仍会保证[2,3]
和[3,2]
不会同时出现(因为3
不会回到2
)
就是肯定会有些晕 但是我觉得也没必要太纠结 就按照逻辑走就行
如果你喜欢这篇文章 欢迎点赞收藏~