Leetcode216-组合总和三
ArrayList<List<Integer>> res=new ArrayList<>(); LinkedList<Integer> integers=new LinkedList<>(); int sum=0; public List<List<Integer>> combinationSum3(int k, int n) { combine(k,n,1); return res; } public void combine(int k,int n,int startIndex) { if (sum != n && integers.size() == k) { return; } if (sum == n && integers.size() == k) { res.add(new LinkedList<Integer>(integers)); } for (int i = startIndex; i <= 9; i++) { sum += i; integers.addFirst(i); //使用addFirst和removeFirst每个integers里面是倒序的 //要正序使用add和removeLast就行了 combine(k, n, i + 1); integers.removeFirst(); sum -= i; } }Leetcode39-组合总和
ArrayList<List<Integer>> res = new ArrayList<>(); LinkedList<Integer> integers = new LinkedList<>(); int sum = 0; public List<List<Integer>> combinationSum(int[] candidates, int target) { combine(candidates, target, 0); return res; } public void combine(int[] candidates, int target, int startIndex) { if (sum > target) { return; } if (sum == target) { res.add(new LinkedList<>(integers)); return; } for (int i = startIndex; i < candidates.length; i++) { sum += candidates[i]; integers.add(candidates[i]); combine(candidates, target, i); integers.removeLast(); sum -= candidates[i]; } }Leetcode40-组合总和二
candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用 一次 ArrayList<List<Integer>> res = new ArrayList<>(); LinkedList<Integer> integers = new LinkedList<>(); int sum = 0; public List<List<Integer>> combinationSum2(int[] candidates, int target) { Arrays.sort(candidates); //加标志数组,用来辅助判断同层节点是否已经遍历 boolean[] flag = new boolean[candidates.length]; combine(candidates, target, 0, flag); return res; } public void combine(int[] candidates, int target, int startIndex, boolean[] flag) { if (sum > target) { return; } if (sum == target) { res.add(new LinkedList<>(integers)); return; } for (int i = startIndex; i < candidates.length; i++) { //出现重复节点直接跳过 if (i > 0 && candidates[i] == candidates[i - 1] && flag[i - 1] == false) { continue; } flag[i] = true; sum += candidates[i]; integers.add(candidates[i]); combine(candidates, target, i + 1, flag); integers.removeLast(); sum -= candidates[i]; flag[i] = false; } }L77-组合
List<List<Integer>> result = new ArrayList<>(); LinkedList<Integer> path = new LinkedList<>(); public List<List<Integer>> combine(int n, int k) { combineRes(n,k,1); return result; } public void combineRes(int n,int k,int startIndex){ //终止条件 if(path.size()==k){ result.add(new ArrayList<>(path));//防止递归操作影响以及保存好的path return; } //剪枝优化 此处仔细想想 //如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了。 //已经选择的元素个数:path.size(); //还需要的元素个数为: k - path.size(); //在集合n中至多要从该起始位置 : n - (k - path.size()) + 1,开始遍历 //不剪枝直接 for(int i=startIndex;i<=n;i++) for(int i=startIndex;i<=n-(k-path.size())+1;i++){ path.addFirst(i); combineRes(n,k,i+1); path.removeFirst(); } }