377. 组合总和 Ⅳ
思路一:回溯法 (超时)
class Solution {
int tmp = 0; // 记录目前组合的和
int res = 0; // 记录目前有的组合的方案种数
LinkedList<Integer> resTmp = new LinkedList<>(); // 记录目前有的组合方案
// 利用nums
public void dfs(int[] nums, int target){
if(tmp>target)
return;
if(target==tmp){
res ++;
System.out.println(resTmp);
System.out.print("==============\n");
return;
}
for(int i=0;i<nums.length;i++){
tmp += nums[i];
resTmp.addLast(nums[i]);
System.out.print("nums[i] = "+nums[i]+"\t"+tmp+"\n");
dfs(nums,target);
tmp -= nums[i];
resTmp.pollLast();
}
}
public int combinationSum4(int[] nums, int target) {
dfs(nums,target);
return res;
}
}
思路二:动态规划
跟爬楼梯那题类似,我们每次都考虑构成和为i的最后一个元素。即有多少种可能构成i-num,再加上最后一个元素到达dp[i]。
换句话说,要想得到i,一定由之前某个i-num (num in nums)得到。
class Solution {
public int combinationSum4(int[] nums, int target) {
int[] dp = new int[target+1]; // dp[i]表示用nums中数字构成的和为i的元素组合的个数
dp[0] = 1;
for(int i=1;i<target+1;i++){
for(int num: nums){
if(i>=num)
dp[i] += dp[i-num];
}
}
return dp[target];
}
}