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]
]
思路
使用回溯法。
- 首先对数组排序。
- 对于[2,3,6,7],target=7,首先找到2,target变成5,再找到2,target变成3,在找到2,此时path = [2,2,2],target变成1,1已经小于path的最后一个值,说明在原数组中已经找不到,则回退一步,变成[2,2],再从[3,6,7]中遍历,找到3
代码
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
result = []
candidates.sort()
self._combinationSum(candidates, target, 0, [], result)
return result
def _combinationSum(self, candidates, target, index, path, res):
if target == 0:
res.append(path)
return
if path and target < path[-1]:
return
for i in range(index, len(candidates)):
self._combinationSum(candidates, target - candidates[i], i, path + [candidates[i]], res)
也可以通过栈来遍历
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
result = []
candidates.sort()
stack = [(0, list(), target)]
can_len = len(candidates)
while stack:
i, path, remain = stack.pop()
while i < can_len:
if candidates[i] == remain:
result.append(path + [candidates[i]])
if path and remain < path[-1]:
break
stack += [(i, path + [candidates[i]], remain - candidates[i])]
i += 1
return result