Given an array of distinct integers nums and a target integer target, return the number of possible combinations that add up totarget.
The test cases are generated so that the answer can fit in a 32-bit integer.
Example 1:
Input: nums = [1,2,3], target = 4
Output: 7
Explanation:
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.
Example 2:
Input: nums = [9], target = 3
Output: 0
Constraints:
1 <= nums.length <= 200
1 <= nums[i] <= 1000
All the elements of nums are unique.
1 <= target <= 1000
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?
Solution:
Version 1: DP
class Solution {
public int combinationSum4(int[] nums, int target) {
if (nums == null || nums.length == 0) return 0;
int n = nums.length;
int[][] dp = new int[target+1][n+1];
//dp[0][...] = 0;
// dp[..][0] = 1;
for(int i = 0; i<=n; i++)
{
dp[0][i] = 1;
}
for(int i = 1; i<= target; i++)
{
for(int j = 1; j<= n; j++)
{
if(i- nums[j-1] >=0)
{
// 注意这里最后是dp[i- nums[j-1]][n]
dp[i][j] = dp[i][j-1] + dp[i- nums[j-1]][n];
}
else
{
dp[i][j] = dp[i][j-1];
}
}
}
return dp[target][n];
}
}
Version 2: Top down dfs+ memorization search (similar as other combination sum)
class Solution {
public int combinationSum4(int[] nums, int target) {
int result = 0;
Arrays.sort(nums);
Map<Integer, Integer> memo = new HashMap<Integer, Integer>();
result = dfs(target, nums, 0, memo);
return result;
}
public int dfs(int count, int[] nums, int startIndex, Map<Integer, Integer> memo)
{
if(memo.containsKey(count))
{
return memo.get(count);
}
if(count == 0)
{
return 1;
}
if(count < 0)
{
return 0;
}
if(startIndex == nums.length)
{
return 0;
}
int result = 0;
for(int i = startIndex; i< nums.length; i++)
{
if(nums[i] > count) continue;
result += dfs(count-nums[i], nums, startIndex, memo);
}
memo.put(count, result);
return result;
}
}