LeetCode:39. Combination Sum

LeetCode:39. Combination Sum

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拼接到每个组合里。后面同理。

Python 代码实现

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值