Combination Sum

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()
原文地址:https://www.cnblogs.com/sherylwang/p/5814448.html