赞
踩
共同特征:都是用一个数组凑出一个目标数,每道题的限制有些不同,都能够用 dfs+回溯+剪枝。传递一个sum参数,判断能否将新的数字加入到ans序列中。
39.组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> ans = new LinkedList<List<Integer>>(); List<Integer> list = new LinkedList<>(); Arrays.sort(candidates);//做一个排序,当前结点的无法组成目标值,那么比他大的数也不可能组成 dfs(ans,list,target,candidates,target,0); return ans; } private void dfs(List<List<Integer>> ans, List<Integer> list, int sum, int[] candidates, int target, int index) { if(sum == 0) { ans.add(new ArrayList<Integer>(list)); } for(int i = index; i < candidates.length; i++) { if(sum - candidates[i] < 0) { break; } list.add(candidates[i]); dfs(ans,list,sum-candidates[i],candidates,target,i); list.remove(list.size()-1); } } }
40.组合总和II
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution { public List<List<Integer>> combinationSum2(int[] candidates, int target) { List<List<Integer>> ans = new LinkedList<List<Integer>>(); List<Integer> list = new LinkedList<>(); Arrays.sort(candidates); dfs(ans,list,candidates,target,target,0); return ans; } private void dfs(List<List<Integer>> ans, List<Integer> list, int[] candidates, int target, int sum, int k) { if(sum == 0) { ans.add(new LinkedList<>(list)); } for(int i = k; i < candidates.length; i++) { if(sum-candidates[i] < 0) { break; } if(i > k && candidates[i] == candidates[i-1]) {//处理重复的情况 continue; } list.add(candidates[i]); dfs(ans,list,candidates,target,sum-candidates[i],i+1); list.remove(list.size()-1); } } }
216.组合总和III
找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
所有数字都是正整数。
解集不能包含重复的组合。
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution { public List<List<Integer>> combinationSum3(int k, int n) { List<Integer> list = new ArrayList<Integer>(); List<List<Integer>> ans = new ArrayList<>(); dfs(n,list,ans,k,1); return ans; } private void dfs(int n, List<Integer> list, List<List<Integer>> ans, int k, int start) { if(n == 0) { if(list.size() == k) { ans.add(new ArrayList<>(list)); } } for(int i = start; i <= 9; i++) { if(n-i >= 0 && list.size() < k && !list.contains(i)) { list.add(i); dfs(n-i, list, ans, k, i+1); list.remove(list.size()-1); } } } }
377.组合总和 IV
给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。
示例:
nums = [1, 2, 3]
target = 4
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。
因此输出为 7。
进阶:
如果给定的数组中含有负数会怎么样?
问题会产生什么变化?
我们需要在题目中添加什么限制来允许负数的出现?
致谢:
特别感谢 @pbrother 添加此问题并创建所有测试用例。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum-iv
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道用的动态规划
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 j = 0; j < nums.length; j++) {
if(i >= nums[j] && dp[i-nums[j]] > 0) {
dp[i] += dp[i-nums[j]];
}
}
}
return dp[target];
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。