leetcode题解-40. Combination Sum II && 216. Combination Sum III
来源:互联网 发布:美橙域名查询 编辑:程序博客网 时间:2024/05/17 21:18
40,题目:
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.Each number in C may only be used once in the combination.Note:All numbers (including target) will be positive integers.The solution set must not contain duplicate combinations.For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6]]
本题与上一题Combination Sum基本上是一样的,不同的是这里的数组可能包含重复的数字,但是在求和的过程中不能重复使用数组里的元素。所以首先我们使用上道题目的思路,直接使用回溯法,但是为了解决数组元素不能重复使用的问题,我们需要做一些小的修改,代码如下所示,有两证改进办法:
public List<List<Integer>> combinationSum2(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(candidates); dfs(candidates, res, new ArrayList<>(), target, 0); return res; } public void dfs(int[] candidates, List<List<Integer>> res, List<Integer> tmp, int target, int idx){ if(target<0) return; else if(target == 0) { //第一种方法,在将list添加到res之前判断re中是否已经包含,比较直观 if(!res.contains(tmp)) res.add(new ArrayList<>(tmp)); } else{ for(int i=idx; i<candidates.length; i++) { //第二种方法,在遍历的过程中加一个判断语句,看前后元素是否相等,如果想等的话则跳过 //if(i > idx && candidates[i] == candidates[i-1]) continue; tmp.add(candidates[i]); //此外,为了不使用重复元素,在递归调用时直接将idx+1即可; dfs(candidates, res, tmp, target-candidates[i], i+1); tmp.remove(tmp.size()-1); } } }
此外,还有一种改进的方法,这种方法在循环过程中加入了判断语句,可以省去一些不必要的循环。如下所示:
public List<List<Integer>> combinationSum2(int[] candidates, int target) { Arrays.sort(candidates); List<List<Integer>> results = new ArrayList<>(); calcCombinationSum2(candidates, 0, new int[candidates.length], 0, target, results); return results; } private void calcCombinationSum2(int[] candidates, int cindex, int[] list, int lindex, int target, List<List<Integer>> results) { if (target == 0) { List<Integer> result = new ArrayList<>(); for (int i = 0; i < lindex; i++) { result.add(list[i]); } results.add(result); return; } int prev = 0; for (int i = cindex; i < candidates.length; i++) { if (candidates[i] != prev) { if (target - candidates[i] < 0) { break; } list[lindex] = candidates[i]; calcCombinationSum2(candidates, i + 1, list, lindex + 1, target - candidates[i], results); prev = candidates[i]; } } }
216, Combination Sum III,题目:
Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.Example 1:Input: k = 3, n = 7Output:[[1,2,4]]Example 2:Input: k = 3, n = 9Output:[[1,2,6], [1,3,5], [2,3,4]]
这道题目相比前两道就简单了,因为只是求1-9之间和为n的k个数,且不可重复使用。首先仍然使用上述思路,使用回溯法,不同的是,这次既要求元素不可重复使用,又规定了k个数求和的限定条件。所以我们按照下述方法进行修改即可:
public static List<List<Integer>> combinationSum3(int k, int n) { List<List<Integer>> res = new ArrayList<>(); int[] nums = {1,2,3,4,5,6,7,8,9}; dfs(nums, res, new ArrayList<>(), n, k, 0); return res; } public static void dfs(int[] nums, List<List<Integer>> res, List<Integer> tmp, int target, int k, int index){ //加上k个数的限制,每加一个数,k减1 if(k < 0 || target < 0) return; else if(k == 0 && target == 0){ res.add(new ArrayList<>(tmp)); return; }else{ for(int i=index; i<nums.length; i++) { tmp.add(nums[i]); dfs(nums, res, tmp, target - nums[i], k - 1, i + 1); tmp.remove(tmp.size()-1); } } }
此外我们还可以不用回溯法,直接使用循环的方式求解,代码入下:
public List<List<Integer>> combinationSum3(int k, int n) { return helper2(k, n, 9);}private List<List<Integer>> helper2(int k, int n, int end) { List<List<Integer>> collection = new ArrayList<List<Integer>>(); //用于记录一次成功的结果 int[] sum = new int[k]; while (true) { //首先,将1-9分配到sum中,便利所有可能组合,要求是k个数和为n while (k > 0 && n > 0 && end > 0) { end = end < n ? end : n; sum[(k--) - 1] = end; n -= end--; } //如果上面的循环满足了k==0且n==0,则将sum记录到res中 if (k == 0 && n == 0) { List<Integer> list = new ArrayList<Integer>(); for (int i : sum) list.add(i); collection.add(list); } //如果sum不满足或者已经记录,则k++,即给sum重新安排数字 if (++k > sum.length) break; //将end和n分别更新 end = sum[k - 1]; n += end--; } return collection;}
0 0
- leetcode题解-40. Combination Sum II && 216. Combination Sum III
- [LeetCode]39.Combination Sum&40.Combination Sum II&216.Combination Sum III&377.Combination Sum IV
- LeetCode 39.Combination Sum,40. Combination Sum II,216. Combination Sum III
- LeetCode 39. Combination Sum && 40. Combination Sum II && 216. Combination Sum III
- LeetCode | Combination Sum & II & III
- Combination Sum III 题解
- 39. Combination Sum 40. Combination Sum II 216. Combination Sum III
- Combination Sum II&III
- Leetcode 39 Combination Sum & 40 Combination Sum II & 216 Combination Sum III & 377 Combination V
- [leetcode] 216.Combination Sum III
- LeetCode 216. Combination Sum III
- 216. Combination Sum III LeetCode
- [leetcode] 216. Combination Sum III
- [LeetCode]216. Combination Sum III
- leetcode 216. Combination Sum III
- LeetCode *** 216. Combination Sum III
- LeetCode 216. Combination Sum III
- leetcode.216. Combination Sum III
- [lydsy] 3224 普通平衡树 [Splay]
- 前端大小屏幕分辨率调试问题——利用火狐或谷歌
- pako.js对数据进行gzip压缩传递到后台解析,解决数据量大的请求问题
- TCP上传图片
- 51nod 1009 数字1的数量
- leetcode题解-40. Combination Sum II && 216. Combination Sum III
- 2013 Asia Hangzhou Regional Contest bnuoj ID: 4771
- C++实现计算器(四则混合运算)
- 石子归并 51nod(区间dp)
- Keychain 讲解
- 搜索练习3 /poj.org/problem 3984 迷宫问题/bfs 回溯找路经
- 确保字符串的每个单词首字母都大写,其余部分小写。
- Failed to read artifact descriptorfor xxx:jar
- 剑指offer-24.二叉树中和为某一值的路径