377. Combination Sum IV 累加和

Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.

Example:

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

The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

Note that different sequences are counted as different combinations.

Therefore the output is 7.

Follow up:
What if negative numbers are allowed in the given array?
How does it change the problem?
What limitation we need to add to the question to allow negative numbers?

题意:给出一个数组和目标和,求数组中的数组成目标和一共有多少种方式。

思路:利用动态规划的思想,用dp[]数组记录每个数能被组合的总的方法,以给出的例子为例:

  • 1的组合总数dp[0]:0 ;
  • 1的组合总数dp[1]:1    --(1) ;
  • 2的组合总数dp[2]:2    --(1,1)、(2);
  • 3的组合总数dp[3]:2    --(1,1,1)、(1,2)、(2,1)、(3);
  • 4的组合总数dp[4]:7   --(1, 1, 1, 1) 、(1, 1, 2) 、(1, 2, 1) 、(1, 3) 、(2, 1, 1) 、(2, 2) 、(3, 1)

其实可以得出前4位数的关系:

  • 如果nums中包含了target,那么target就能被nums中这一个数组合。
  • 如果nums中存在比target小的数num[i],那么target的组合数就能累加上(target-nums[i])的组合数,如当target=3,遍历nums中小于等于target的数num:
    • 当num=1,dp[1]=1, dp[target-num]=dp[3-1]=dp[2]=2; 
    • 当num=2,dp[2]=2,dp[target-num]=dp[3-2]=dp[1]=1; 
    • 当num=3,dp[3]=1,dp[target-num]=dp[3-3]=dp[0]=0; (dp[3]=1是因为已知一种可直接组合成target=3的方式:当num=3)

可以得出结论:dp[3]=dp[3]+dp[3-1]+dp[3-2]+dp[3-3]=dp[3]+dp[2]+dp[1]+dp[0]=1+2+1=4.

总结成公式:当nums[]中的数num<=target,

dp[target] = dp[target] + dp[target-nums1] + dp[target-nums2] +···+ dp[target-numsN]

(numN<=target);

代码:

class Solution {
    public int combinationSum4(int[] nums, int target) {
        int length = nums.length;
        int[] dp = new int[target+1];
        for(int num:nums){
            if(num<=target){
                dp[num]=1;   //自身就能形成一种组合方式
            }
        }
        
        for(int i=1;i<=target;i++){
            for(int num:nums){
                if(num<=i){
                    int subNum = i-num;
                    dp[i]+=dp[subNum]; //自身的组合总数 = (自身-数组中存在的数)的组合总数
                }
            }
        }
        return dp[target];
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值