2024.4.22
题目来源
我的题解
方法一 回溯+记忆化
和组合总和二、三类似,只是需要使用记忆化记录重复的地方(剪枝),不然时间上过不去
时间复杂度:这个时间复杂度把握不准。
空间复杂度:O(target)
class Solution {
int res=0;
public int combinationSum4(int[] nums, int target) {
int n=nums.length;
int[] memo=new int[target+1];
Arrays.sort(nums);
Arrays.fill(memo,-1);
dfs(nums,target,memo);
return res;
}
public void dfs(int[] nums,int target,int[] memo){
if(target==0)
res++;
if(target<0)
return;
for(int i=0;i<nums.length;i++){
if(target-nums[i]<0)
break;
//当已经计算过target-nums[i]的组合数后直接使用该组合数
if(memo[target-nums[i]]!=-1)
res+=memo[target-nums[i]];
else{
//记录target-nums[i]之前的组合数
int t=res;
dfs(nums,target-nums[i],memo);
//总的res-之前暂存记录target-nums[i]之前的组合数,得到target-nums[i]的组合数
memo[target-nums[i]]=res-t;
}
}
}
}
方法二 动态规划
参考官方题解
时间复杂度:O(target×n),其中 target 是目标值,nnn 是数组 nums 的长度。需要计算长度为 target+1 的数组 dp 的每个元素的值,对于每个元素,需要遍历数组 nums 之后计算元素值。
空间复杂度:O(target)。需要创建长度为 target+1 的数组 dp。
class Solution {
public int combinationSum4(int[] nums, int target) {
int[] dp = new int[target + 1];
dp[0] = 1;
for (int i = 1; i <= target; i++) {
for (int num : nums) {
if (num <= i) {
dp[i] += dp[i - num];
}
}
}
return dp[target];
}
}
有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~