Description
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?
Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.
分析
题目的意思是:给你一堆数字,还给你一个target,求所有可能的数字组合等于target的组合。
dp[i]表示和为i的组合方法数,dp[target]就是我们所求的内容。这个dp的推导很简单,求种类数就是:
dp[i]=dp[i]+dp[i-val] val为nums中的数字
代码
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
if(nums.empty()){
return 0;
}
int n=target+1;
vector<int> dp(n,0);
dp[0]=1;
for(int i=1;i<n;i++){
for(auto val:nums){
if(i-val>=0){
dp[i]+=dp[i-val];
}
}
}
return dp[target];
}
};
Python代码
最开始写代码的时候,是仿照0,1背包问题解的,即两层循环,外层是背包的物品,内层遍历价值,然后就翻车了。递推公式还是很好推的:
dp[0]=1表示什么都不选,所以组合数为1.
递推公式为:dp[i]=dp[i]+dp[i-num]
class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
dp =[0 for _ in range(target+1)]
dp[0]=1
for i in range(target+1):
for num in nums:
if i>=num:
dp[i]+=dp[i-num]
return dp[target]