377. 组合总和 Ⅳ

给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

示例:

nums = [1, 2, 3]
target = 4

所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

请注意,顺序不同的序列被视作不同的组合。

因此输出为 7。

 

思路一:递归 DFS    f(target)=+f(target-nums[i])    超时  待优化

class Solution(object):

    def combinationSum4(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
#         背包问题
#     方法一:递归 f[n]+=f[n-num]  dfs解决
        if target<0:return 0
        if target==0:return 1
        res=0
        for num in nums:
            res+=self.combinationSum4(nums,target-num)
        return res

 

 

法二 动态规划  dp[target]=dp[target-nums[0]]+dp[target-nums[1]]+...

class Solution(object):
    
        
    def combinationSum4(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
       
#         完全背包问题 动态规划  dp[target]=dp[target-nums[0]]+dp[target-num[1]]+...  #target-num>=0
        
         dp=[0]*(target+1)
         为了计算dp[1],dp[1]=dp[1-1]
         dp[0]=1
         for i in range(1,1+target):
             for num in nums:
                 if i-num>=0:
                     dp[i]+=dp[i-num]
         return dp[target]

    
    

 

法三  记忆化搜索

class Solution(object):
    
        
    def combinationSum4(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """

#     记忆化搜索  dfs过程中保存结果值到矩阵中 下次访问到该状态直接返回
#     -1表示还未访问过    
        self.memo=[-1]*(target+1)
        self.memo[0]=1
        return self.dfs(nums,target)
    
    def dfs(self,nums,target):
            '''
            搜索的是当前target下的可能组合数
            '''
            if self.memo[target]!=-1:return self.memo[target]
            res=0
            for num in nums:
                if target>=num:
                    res+=self.dfs(nums,target-num)
            self.memo[target]=res
            return res
    
    

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值