題目要求
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?
有一個不包含重複值的正整數數組nums,問從數組中選擇幾個數,其和爲target,這樣的數的組合有幾種?
思路一:自頂向下的dp
這題本質上需要注意一點,就是我如果需要組成target,那麼一定是由nums中的一個值和另一個值的排列組合結果構成的。比如com[4] = com[4-1] + com[4-2] + com[4-1]。通過這一點,我們構成一個遞歸表達式,但是因爲單純的遞歸表達式沒有計算中間結果,所以會造成大量重複的計算影響效率,所以這裏採用dp的思路額外的用數組來記錄已經計算過的com結果。比如com[3] = com[2] + com[1], com[2] = com[1],如果沒有dp,則需要重複計算com[1]的結果。
public int combinationSum4(int[] nums, int target) {
if (nums == null || nums.length < 1) {
return 0;
}
int[] dp = new int[target + 1];
Arrays.fill(dp, -1);
dp[0] = 1;
return helper(nums, target, dp);
}
private int helper(int[] nums, int target, int[] dp) {
if (dp[target] != -1) {
return dp[target];
}
int res = 0;
for (int i = 0; i < nums.length; i++) {
if (target >= nums[i]) {
res += helper(nums, target - nums[i], dp);
}
}
dp[target] = res;
return res;
}
思路二:自底向上dp
public int combinationSum4(int[] nums, int target) {
Arrays.sort(nums);
int[] combinationCount = new int[target+1];
combinationCount[0] = 1;
for(int i = 1 ; i<=target ; i++) {
for(int j = 0 ; j<nums.length && nums[j] <= i ; j++) {
combinationCount[i] += combinationCount[i - nums[j]];
}
}
return combinationCount[target];
}