题目描述查看:https://leetcode-cn.com/problems/combination-sum/
题目的意思是从一个给定的数组中,选出一些数,这些数的和是target。
1.回溯法
-
思路
回溯法有2个关键点,一个是已经选的数,另一个是还能选哪些数。
创建一个List<Integer>参数用来保存已经选的数。
设定begain记录已经搜索过的组合,回溯法是深度优先搜索的思想,不必在考虑上层选择过之前节点的值。
设定List<List<Integer>> res参数保存最终结果。
private static void combinationSumHelper(int[] candidates, int target,List<Integer> choose,List<List<Integer>> res,int begain)
-
回溯法框架
回溯法需要在递归的过程中,记录自己选过的数,明确自己还能选哪些数。
1 public void backTrack(已选,还能选,结果集){ 2 if(满足结束条件){ 3 结果集.add(已选); 4 return; 5 } 6 7 for (int i = 0; i < 还能选.length; i++) { 8 已选.add(还能选[i]); 9 backTrack(); 10 已选.remove(还能选[i]); 11 } 12 }
-
代码
1 public List<List<Integer>> combinationSum(int[] candidates, int target) { 2 List<List<Integer>> res = new ArrayList<>(); 3 Arrays.sort(candidates); 4 List<Integer> choose = new ArrayList<>(); 5 combinationSumHelper(candidates,target,choose,res,0); 6 return res; 7 } 8 9 private void combinationSumHelper(int[] candidates, int target,List<Integer> choose,List<List<Integer>> res,int begain){ 10 if(target < 0)return; 11 else if(target == 0){ 12 res.add(new ArrayList<>(choose)); 13 } 14 15 for (int i = begain;i<candidates.length;i++){ 16 //做选择 17 choose.add(candidates[i]); 18 combinationSumHelper(candidates,target-candidates[i],choose,res,i); 19 choose.remove(choose.size()-1); 20 } 21 }