解决思路
回溯算法 + 剪枝
code
public List<List<Integer>> combinationSum2(int[] candidates, int target) {int len = candidates.length;List<List<Integer>> res = new ArrayList<>();if (len == 0) {return res;}// 先将数组排序,这一步很关键Arrays.sort(candidates);Deque<Integer> path = new ArrayDeque<>(len);dfs(candidates,len,0,target,path,res);return res;}/*** @param candidates 候选数组* @param len* @param begin 从候选数组的 begin 位置开始搜索* @param residue 表示剩余,这个值一开始等于 target,基于题目中说明的"所有数字(包括目标数)都是正整数"这个条件* @param path 从根结点到叶子结点的路径* @param res*/private void dfs(int[] candidates,int len,int begin,int residue,Deque<Integer> path, List<List<Integer>> res){if (residue == 0) {res.add(new ArrayList<>(path));return;}for (int i = begin;i < len;i++){// 大剪枝if (residue - candidates[i] < 0)break;// 小剪枝if (i > begin && candidates[i] == candidates[i - 1])continue;path.addLast(candidates[i]);// 因为元素不可以重复使用,这里递归传递下去的是 i + 1 而不是 idfs(candidates,len,i+1,residue - candidates[i],path,res);path.removeLast();}};


