April——377.组合综合IV

 


 

class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:

        #dp[i]代表当target为i的时候组合个数
        #假如是5
        #4的组合数+1
        #3的组合数+2
        #2的组合数+3
        #1的组合数+4
        
        dp = [0]*(target+1)
        dp[0] = 1
        for i in range(1,target+1):
            for num in nums:
                if i>=num:
                    dp[i]+=dp[i-num]

        return dp[-1]


        #回溯直接超时了
        # if min(nums)>target:
        #     return 0
        # res = []
        # def huisu(index,res,path):
        #     if sum(path)==target:
        #         res.append(0)
        #         return 
        #     if sum(path)>target or nums[index]>target:
        #         return 

        #     for i in range(len(nums)):
        #         path.append(nums[i])
        #         huisu(0,res,path)
        #         path.pop()
        # path = []
        # huisu(0,res,path)
        # return len(res)

        


回溯算法完全暴力出超时,因此使用背包的思想,从动态转移的思路去求解这个问题

 

定义dp[i]表示和为i的组合个数,那么这个dp[i]怎么求呢。举个例子,比如i是5,如果要找和为5的组合,

我们可以用和为1的组合加上一个4
或者用和为2的组合加上3
或者用和为3的组合加上2
或者用和为4的组合加上1
而和为1,2,3,4的组合个数分别是dp[1],dp[2],dp[3],dp[4]。

所以和为5的组合个数就是他们几个的和,也就是dp[5]=dp[1]+dp[2]+dp[3]+dp[4];

但这里会有个问题,假如数组nums中没有2,我们是没法用和为3的组合加上2的,因为这里根本就没有2可选。那我们能选的数字有哪些呢,其实就是数组nums中元素。

所以上面的推理我们再来改一下

 

如果要求dp[i]

我们可以用和为i-nums[0]的组合再加上nums[0]
或者用和为i-nums[1]的组合再加上nums[1]
或者用和为i-nums[2]的组合再加上nums[2]
………
所以dp[i]的组合个数就是他们的累加,也就是dp[i]=dp[i-nums[0]]+dp[i-nums[1]]+……。

但这里还要注意一点,就是i-nums[j]不能小于0。

reference:https://leetcode-cn.com/problems/combination-sum-iv/solution/shu-ju-jie-gou-he-suan-fa-dong-tai-gui-h-jain/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值