原题
Given a set of candidate numbers (candidates
) (without duplicates) and a target number (target
), find all unique combinations in candidates where the candidate
numbers sums to target
.
The same repeated number may be chosen from candidates
unlimited number of times.
Note:
- All numbers (including target) will be positive integers.
- The solution set must not contain duplicate combinations.
题目:
给定一组候选数字 (候选) (不带重复项) 和目标数字 (目标), 可以在候选数字总和为目标的候选项中查找所有唯一的组合。
同样重复的数字可以从候选者无限次数中选择。
Example 1:
Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]
Example 2:
Input: candidates = [2,3,5], target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
Reference Answer
思路分析
本题采用回溯算法。
- 基本思路是先排好序,这样做的目的是为了对数组后面不可能出现的情况进行排除,有利于减少查找时间,即剪枝操作
- 外层循环对数组元素依次进行遍历,依次将 nums 中的元素加入中间集,一旦满足条件,就将中间集加入结果集
- 然后每次递归中把剩下的元素一一加到结果集合中,并且把目标减去加入的元素,然后把剩下元素(包括当前加入的元素)放到下一层递归中解决子问题。
class Solution:
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
candidates.sort()
Solution.res = []
self.DFS(candidates, target, 0, [])
return Solution.res
def DFS(self, candidates, target, start, temp_res):
if target == 0:
Solution.res.append(temp_res)
return
for i in range(start, len(candidates)):
if candidates[i] > target:
return
self.DFS(candidates, target - candidates[i], i, temp_res + [candidates[i]])
反思:
- 对于这种需要遍历所有可能情况的,优先考虑回溯法;
- 自己做的过程尝试正序依次求出所有答案,这种做法太傻,计算复杂度也太高;
- 要注意列表的复制:
res = candidates[:]
才是真正意义上的复制(重新分配了空间,并按照candidates对应元素进行了赋值);而直接res = temp_res.append(candidates[i])
只是将list空间做了复制,操作的依旧还是temp_res地址的list。