LeetCode - 39. Combination Sum
来源:互联网 发布:object 数组添加 编辑:程序博客网 时间:2024/05/18 12:34
这道题要求我们找出所有的可行解,一般这种问题我们可以考虑使用backtracking或DFS,通常情况下,我们将回溯法与DFS同等看待,可以用一个等式表示它们的关系:回溯法 = DFS + 剪枝。所以回溯法是DFS的延伸,其目的在于通过剪枝使得在DFS过程中如果满足了回溯条件不必找到叶子结点,就截断这条路径,从而加速DFS。实际上,即使没有剪枝,DFS从下层退回上层的时候也是一个回溯的过程,通常用递归的形式实现比较直观。
但问题是自己水平和能力比较低,即使是在知道要使用backtracking的情况下,依然写不出backtrack函数,通常backtrack函数的参数列表包括:所有解的集合,以便找到可行解的时候将可行解加入其中;当前的解;数据,比如这道题目中的candidates[];目标随着backtracking变化的情况,比如这道题的remain;以及其他辅助的相关变量,比如这道题目中的start。刚刚看到这个解答的时候我有三个地方不是很理解:
1. 为什么在backtrack之前需要对元素进行排序?后来自己试了一下,发现是不用的
2. 为什么要使用list.add(new ArrayList<>(solution))而不是list.add(solution)?
因为solution的类型是ArrayList<Integer>,而它是随着backtracking的过程而不断变化的。如果使用后面这个写法,那么向list中加入的只是一个reference,它指向的内存中元素是在不断变化的,所以要使用前面的写法。进而进一步地推广,在backtracking或者其他问题中,如果想某个容器中添加某个object的时候,最好new一个新的出来加入,而不是直接把当前的object的reference加进来。
3. 为什么在backtrack之后要remove solution中的最后一个元素?
这是在backtacking向上回溯的时候,需要一步一步地删除以前加入的元素,如果没有这一句的话,那么上一条路径的solution也会一直保存在solution中,整个过程如下图所示:
代码如下:
public class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> list = new ArrayList<List<Integer>>(); // Arrays.sort(candidates); backtrack(list, new ArrayList<>(), candidates, target, 0); return list; } private void backtrack(List<List<Integer>> list, List<Integer> solution, int[] candidates, int remain, int start){ if(remain < 0) return; if(remain == 0) { list.add(new ArrayList<>(solution)); return; } // remain > 0 for(int i = start; i < candidates.length; i++){ solution.add(candidates[i]); backtrack(list, solution, candidates, remain - candidates[i], i); // not i + 1 because we can reuse same elements solution.remove(solution.size() - 1); } }}
知识点:
1. 上面三个不明白的问题要多想想,都是非常值得注意的细节,要记住
2. 在backtracking或者DFS的时候,最好像上面的图片一样把调用的过程画出来,这样就会清晰很多
- [LeetCode]39.Combination Sum
- LeetCode --- 39. Combination Sum
- LeetCode 39.Combination Sum
- [Leetcode] 39. Combination Sum
- Leetcode-39.Combination Sum
- LeetCode 39. Combination Sum
- [LeetCode]39. Combination Sum
- 39. Combination Sum LeetCode
- [leetcode] 39. Combination Sum
- leetcode 39. Combination Sum
- 【leetcode】 39. Combination Sum
- LeetCode 39. Combination Sum
- leetcode 39. Combination Sum
- LeetCode 39. Combination Sum
- LeetCode *** 39. Combination Sum
- LeetCode 39. Combination Sum
- leetcode 39. Combination Sum
- LeetCode - 39. Combination Sum
- 如何撰写一篇受人欢迎的博客
- Makefile分析
- 【模板】可持久化线段树
- HDU2521 求因数个数
- [bash]fgrep
- LeetCode - 39. Combination Sum
- Nginx配置文件nginx.conf中文详解
- POJ 1952 Buy Low,Buy Lower
- C语言的值传递、地址传递、引用传递
- 判断一个年份是否是闰年Java初级入门
- linux后台运行和关闭、查看后台任务
- 网页设计的字体
- 【Spring 1】Spring简介
- android stuido常见问题查询网址(此贴不定期更新)