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?
Analysis:
Define function F(n) = num of possible combinations that add up to n
therefore
nums= [a0, a1, a2, ....]
then :
F(n)= F(n-a0)+F(n-a1)+F(n-a2)+..
Therefore, we can build our answer in Top-Down (memorization) or Bottom-Up way (Dynamic Programming).
For Top-Down way, we use a HashMap to record the F(k)
value if it has been calculated.
For Dynamic Programming approach, we define int[] dp=new int[target+1]
where dp[i] represent the number of combinations that add up to i
. To calculate dp[i] for i we have to build the answer to number j where j is smaller than i first.
Solution
Memorization
public class Solution {
Map<Integer, Integer> map = new HashMap<>();
public int combinationSum4(int[] nums, int target) {
int count = 0;
if (nums == null || nums.length ==0 || target < 0 ) return 0;
if ( target ==0 ) return 1;
if (map.containsKey(target)) return map.get(target);
for (int num: nums){
count += combinationSum4(nums, target-num);
}
map.put(target, count);
return count;
}
}
DP
public class Solution {
public int combinationSum4(int[] nums, int target) {
if(nums==null || nums.length==0) return 0;
int[] dp=new int[target+1];
Arrays.sort(nums);
for(int i=1;i<=target;i++){
for(int a:nums){
if(a>i) break;
if(a==i) dp[i]+=1;
else dp[i]+=dp[i-a];
}
}
return dp[target];
}
}