题目:
Given aninteger array with allpositive numbers and no duplicates, find the number of possible combinations that add up to apositive 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.题目解读: 给一个不重复的正整数数组,从该数组中挑选一些数组合相加等于给定的正整数,问这种组合方式有多少种,注意一个trick:数组中的元素是可以反复挑选的。
recursive solution.
思路:comb[target] = sum(comb[target - nums[i]]), where 0 <= i < nums.length, and target >= nums[i]
这种做法有大量的重复计算。而且出现了Time Limit Exceeded
class Solution {
public int combinationSum4(int[] nums, int target) {
if(target == 0) return 1;
int res = 0;
for(int i = 0; i< nums.length; i++){
if(target >= nums[i])
res += combinationSum4(nums,target-nums[i]);
}
return res;
}
}
改造成DP,加入备忘录
dp[i],累加到i有多少种组合
Top-down
Time Limit Exceeded
class Solution {
public int[] dp;
public int combinationSum4(int[] nums, int target) {
dp = new int[target+1];
//初始化dp
Arrays.fill(dp,-1);
dp[0] = 1;
return helper(nums,target);
}
public int helper(int[] nums,int target){
//先判断是否已经计算过了,避免重复计算
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[target] = res;
return res;
}
}
//bottom_up
class Solution {
public int combinationSum4(int[] nums, int target) {
//定义dp 累加到i有多少种组合
int[] dp = new int[target+1];
dp[0] = 1;
//这种做法没有考虑元素重复
// for(int j = 0; j < nums.length; j++){
// for(int i = target; i >= nums[j]; i--){
// dp[i] += dp[i-nums[j]];
// }
// }
for(int i = 1; i < dp.length; i++){
for(int j = 0; j < nums.length; j++){
if(i >= nums[j])
dp[i] += dp[i-nums[j]];
}
}
return dp[target];
}
}