LeetCode笔记-40-组合总和

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

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

backtrack步骤如下:

  1. 剪枝:如果当前tmp数组的和cur已经大于目标target,没必要枚举了,直接return
  2. 如果当前tmp数组的和cur正好和目标target相等,找到一个组合,加到结果res中去,并return
  3. for循环遍历从index开始的数,选一个数进入下一层递归。因为数可以重复,所以在进入下一层递归时,i没有加1,当前数candidates[i]可以再次被选择
class Solution:
    def combinationSum(self, candidates: List[int],
                       target: int) -> List[List[int]]:
        def backtrack(temp, cur, index):
            if cur == target:
                res.append(temp)
            if cur > target:
                return
            for i in range(index, n):
                backtrack(temp + [candidates[i]], cur + candidates[i], i)

        res = []
        n = len(candidates)
        backtrack([], 0, 0)
        return res

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

数组 candidates 有序,也是 深度优先遍历 过程中实现「剪枝」的前提。
将数组先排序的思路来自于这个问题:去掉一个数组中重复的元素。

先对数组 升序 排序,重复的元素一定不是排好序以后相同的连续数组区域的第 1 个元素。也就是说,剪枝发生在:同一层数值相同的结点第 2、3 ... 个结点,因为数值相同的第 1 个结点已经搜索出了包含了这个数值的全部结果同一层的其它结点搜索出的结果一定不会比第 1 个结点更多,并且是第 1 个结点的子集

image.png

class Solution:
    def combinationSum2(self, candidates: List[int],
                        target: int) -> List[List[int]]:
        def backtrack(temp, cur, index):
            if cur == target:
                res.append(temp)
            if cur > target:
                return
            for i in range(index, n):
                if i > index and candidates[i] == candidates[i - 1]: continue
                backtrack(temp + [candidates[i]], cur + candidates[i], i+1)

        res = []
        candidates.sort()
        n = len(candidates)
        backtrack([], 0, 0)
        return res

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值