回溯法

39. 组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。 
示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]

class Solution:
    def combinationSum(self, candidates, target: int):
        if not candidates: return []
        if min(candidates)>target:  return []
        candidates.sort()
        res = []
        
        def helper(candidates, target, temp_list):
            if target==0:
                res.append(temp_list)
            if target<0:
                return
            for i in range(len(candidates)):
                if candidates[i]>target:
                    break
                helper(candidates[i:], target-candidates[i], temp_list+[candidates[i]])
        helper(candidates, target, [])
        return res

 

40. 组合总和 II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。 
示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

class Solution:
    def combinationSum2(self, candidates, target: int):
        if not candidates:
            return []
        candidates.sort()
        n = len(candidates)
        res = []
        
        def backtrack(i, tmp_sum, tmp_list):
            if tmp_sum == target:
                res.append(tmp_list)
                return 
            for j in range(i, n):
                if tmp_sum + candidates[j]  > target : break
                if j > i and candidates[j] == candidates[j-1]:continue   # 防止结果中有重复数组
                backtrack(j + 1, tmp_sum + candidates[j], tmp_list + [candidates[j]])
        backtrack(0, 0, [])    
        return res

 参考:https://leetcode-cn.com/problems/combination-sum/solution/xue-yi-tao-zou-tian-xia-hui-su-suan-fa-by-powcai/

 一个demo:

a = [1,2,4,7,4,21,23,9,22, 6,7,9,13,17,18,19]
a = sorted(a)
target = 24

def dfs(i,temp,lists,target,res,n,a):
    if temp==target:
        res.append(lists)
        return 
    for j in range(i,n):
        if temp+a[j]>target:
            break
        if j>i and a[j]==a[j-1]:
            continue
        dfs(j+1, temp+a[j], lists+[a[j]], target, res, n,a)
    return res

n = len(a)        
print(dfs(0, 0, [], target, [], n,a))
View Code

 

 

216. 组合总和 III

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

所有数字都是正整数。
解集不能包含重复的组合。 
示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]

 

class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        index,res = 0, []
        nums = list(range(1,10))
        self.dfs(nums, k, n, index, [], res)
        return res
        
    def dfs(self, nums, k, n, index, path, res):
        if k<0 or n<0:
            return 
        if k==0 and n==0:
            res.append(path)
        for i in range(index, len(nums)):
            self.dfs(nums, k-1, n-nums[i], i+1, path+[nums[i]], res)

 

posted @ 2019-08-05 22:16  三年一梦  阅读(208)  评论(0)    收藏  举报