39.组合总和

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]
]

思路

使用回溯法。

  1. 首先对数组排序。
  2. 对于[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

你可能感兴趣的:(39.组合总和)