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:
1. All numbers (including target) will be positive integers.
2. The solution set must not contain duplicate combinations.
Example:
Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]
就是给定一个数组以及一个目标值。要从数组中求出所有数字组合的和为目标值,一个数字允许重复。
思路一:回溯法
先对数组进行一次升序排列。然后我们遍历这个数组,用目标值减去每个数值,得到一个差值。这样就变成了数组中得每个数值和这个差值的组合数组再做排列就可以了。比如这里目标值为7,遍历数组,7-2=5,我们只要求出5的组合情况,再把2拼接到每个组合里。后面同理。
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
res = []
resSet = set()
for c in candidates:
remain = target-c
if remain >= candidates[0] or remain == 0:
# remain = 0 时需要拼接一个c数组。
if remain == 0:
res.append([c])
# 求出remain的组合情况
remainArray = self.combinationSum(candidates, remain)
if remainArray is not None and len(remainArray) > 0:
for ra in remainArray:
ra.append(c)
res.append(ra)
# 去重
ans = []
for r in res:
r.sort()
resSet.add(tuple(r))
for rs in resSet:
ans.append(list(rs))
return ans
思路二:DFS
def combinationSum(self, candidates, target):
res = []
candidates.sort()
self.dfs(candidates, target, 0, [], res)
return res
def dfs(self, nums, target, index, path, res):
if target < 0:
return # backtracking
if target == 0:
res.append(path)
return
for i in xrange(index, len(nums)):
self.dfs(nums, target-nums[i], i, path+[nums[i]], res)
THE END.