Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
- All numbers (including target) will be positive integers.
- The solution set must not contain duplicate combinations.
For example, given candidate set [2, 3, 6, 7]
and target 7
,
A solution set is:
[ [7], [2, 2, 3] ]
组合的题目,一系列当中的第一道,每个元素都可以被选择无数次,但是要求结果不能有重复.但是重复的定义这里也非常奇怪.
[2,2,3] target为7时,一共有3个结果[[2,2,3],[2,2,3],[2,2,3]]即第一个元素出现2次,第二个元素出现2次,第一个和第二个元素各出现一次.
所以一个简单的方法是,选择元素的时候只能向后推进,不能朝前退.这样一个元素重复出现多次的时候,都是出现在一块.总体的返回结果每个都是一个增序序列.复杂度为O(n!).另外如path sum的思路一样,可以将target转化为当前的残差.代码如下:
class Solution(object): def combinationSum(self, candidates, target): """ :type candidates: List[int] :type target: int :rtype: List[List[int]] """ #reverse order, then mirror to get the final result. if not candidates: return [] res = [] candidates.sort() self.search(candidates, res, target, [], 0) return res def search(self, candidates, res, target, cur, index): if target == 0: res.append(cur+[]) return for i in xrange(index, len(candidates)): if candidates[i] <= target: cur.append(candidates[i]) self.search(candidates, res, target - candidates[i], cur, i) cur.pop()
如果需要返回结果完全没有重复,则有重复元素时,只能反复枚举第一个元素,[2,2,3]这个例子中就是只能反复枚举第一个2,这样避免了第一种情况的重复,代码如下:
class Solution: # @param candidates, a list of integers # @param target, integer # @return a list of lists of integers def combinationSum(self, candidates, target): if not candidates: return [] res = [] candidates.sort() self.search(candidates, res, target, [], 0) return res def search(self, candidates, res, target, cur, start): if target == 0: res.append(cur+[]) return for i in xrange(start, len(candidates)): if i > start and candidates[i] == candidates[i-1]: continue if candidates[i] <= target: cur.append(candidates[i]) self.search(candidates, res, target - candidates[i], cur, i) cur.pop()