leetcode39.组合总数

题目:

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。

示例:

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

思路:

回溯法,这里分剪枝和不剪枝两种方法,剪枝可以降低计算复杂度,使计算过程更简化。
不剪枝过程,目的是在数组中找到所有和为target的组合,这个数组中的数可以重复利用,但是解的集合中不能包括重复的解。

1.比如目标是7,数组是[2,3,6,7],来数组中找,每一次找都可以用2,3,6,7这四个数,先找2,用上2了,7-2为5,还差5,还去数组中找,依次找,用上2,5-2为3,还差3,还去数组中找,依次找,还是用2,还差1,这次找1,能找到1的话,就找到一条路径了,如果结果小于0,那这条路径肯定不满足,如果结果大于0,我们还能在数组中找,现在来看,数组中首选也就是第一位的是2,1-2是负值了,这条路径肯定不行,再找3,6,7发现都不行。
2.再往上一层级上返回,差3,用完2了,用3,发现正好满足,2+2+3,返回一条路径,这样2和3都用完了,用后边的6,7看是否能得到3,发现都不行。
3.再往上一级返回,一开始用2,差5,为得到5找了2,现在找3,那就需要5-3为2了,这里要注意,前面2的时候找了3,这里3的时候就不要找2了,避免结果的重复,然后就找3,6,7,发现2减去这几个数都是负值,就不行了。
4.同样思路遍历第二层里的6,7,第一层里的3,6,7.

可以看看题解里的图,很清晰。
代码解析,长度为0,直接返回空,开后调用函数,进入循环,结果小于0,返回,看下一数,结果等于0,在结果中加入这一路径,看下一个数,要注意同级中,前面遍历过的数,后面不遍历了,是通过最内层循环里索引i作为再调用dfs函数的开始位置来实现的。
剪枝法,可以先将数组中的数由小到大排序,如果前面的数不满足情况,后面的更不满足,就可以直接返回,进行上一层级的遍历。

class Solution(object):
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        #不剪枝,不需要排序,深度优先遍历,回溯法,
        if len(candidates)==0:
            return []
        def dfs(candidates,begin,size,res,path,target):
            if target<0:
                return
            if target==0:
                res.append(path)
                return
            for i in range(begin,size):
                dfs(candidates,i,size,res,path+[candidates[i]],target-candidates[i])
        size = len(candidates)
        path = []
        res = []
        dfs(candidates,0,size,res,path,target)
        return res
# 解法2:
# 剪枝,排序,当前面的小于0时就不用遍历后边的了,肯定不成立
        if len(candidates)==0:
            return []
        def dfs(candidates,begin,size,res,path,target):
            if target==0:
                res.append(path)
                return
            for i in range(begin,size):
                residue = target-candidates[i]
                if residue < 0:
                    break
                dfs(candidates,i,size,res,path+[candidates[i]],residue)
        size = len(candidates)
        path = []
        res = []
        candidates.sort()
        dfs(candidates,0,size,res,path,target)
        return res
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值