LeetCode | 216. Combination Sum III BFS

Findall possible combinations of k numbers that add up to a number n,given that only numbers from 1 to 9 can be used and each combination should bea unique set of numbers.



Example1:

Input: k =3, n = 7

Output:

[[1,2,4]]



Example2:

Input: k =3, n = 9

Output:

[[1,2,6], [1,3,5], [2,3,4]]

这一题我是使用BFS做的,最后打败了87%的提交

首先这一题可以使用DFS做,但是使用DFS的话函数栈会占用很多额外的空间,耗费更多的时间,用迭代的形式使用BFS做会更快

这一题有非常多的可以剪枝的地方

首先对于某个k和n而言,

当if n < 45 -theCount[k + 1] or n > theCount[9 - k + 1]:的时候,说明这个时候n大于当前k个元素可以取得的最大值或者是最小值,比如当k为3的时候,可以取得的最小值是1 + 2 + 3 = 6,可以取的的最大值是7 + 8 + 9 =24,这个时候可以直接return

使用一个栈来theDp存储已经取得的数(使用的并不是Dp),当theDp中的最后一个数是i的时候,下一个数可以在i + 1 ~ 9的范围取,当剩下的数的个数也就是9 – i – 1 +1不足以凑够k个数的时候,可以剪枝,

当剩下所有数的和也就是(i+ 1) +( i+ 2) +( i + 3)…+9和sum(Dp)相加小于n的时候,说明剩下的数全部加起来在加上theDp里面的数都不能到达n,这个时候也可以剪枝,

当theDp中的数的个数>= k的时候,说明已经取了k个数,没有必要往下取,可以剪枝

通过这一题我学会了,python里面,数组赋值并不是复制,而是把地址进行传递,要想复制值得用extend,类的对象的声明使用aa = solution()(这一点和C++一样)

class Solution(object):
    def combinationSum3(self, k, n):
        """
        :type k: int
        :type n: int
        :rtype: List[List[int]]
        """
        theCount = [0 for i in range(11)]
        for i in range(9, 0, -1):
            theCount[i] = i + theCount[i + 1]

        result = []

        if k > 9 or k <= 0:
            return result

        if n < 45 - theCount[k + 1] or n > theCount[9 - k + 1]:
            return result

        theDp = [[i] for i in range(1, 10)]
        while len(theDp):
            tmp = theDp.pop(0)

            if len(tmp) == k:
                if sum(tmp) == n:
                    result.append(tmp)
                continue

            theKNeed = k - len(tmp)
            for i in range(tmp[-1] + 1, 10):
                if 9 - i + 1 >= theKNeed and sum(tmp) + theCount[i] >= n:
                    tmp2 = []
                    tmp2.extend(tmp)
                    tmp2.append(i)
                    theDp.append(tmp2)
        return result
        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值