2024.4.22
- 题目来源
- 我的题解
- 方法一 回溯+记忆化
- 方法二 动态规划
题目来源
力扣每日一题;题序:377
我的题解
方法一 回溯+记忆化
和组合总和二、三类似,只是需要使用记忆化记录重复的地方(剪枝),不然时间上过不去
时间复杂度:这个时间复杂度把握不准。
空间复杂度: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];}
}
有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~