NO.40 组合总和 II 中等
本题和徒手挖地球十二周目中组合总和的思路一样只是少量变化,区别在于本题candidate数组中的元素不能重复使用(只能使用一次),本题数组中有重复元素。
思路一:深度优先遍历,回溯法 从39题组合总和的基础上进行分析改进:
- 本题数组中的每个元素不能重复使用,但是数组中存在重复元素(每个相等元素都可以使用一次)
- 每个节点的孩子应该使用下一个元素开始,即不再是index而是index+1;
- 本题数组中存在重复元素,所以仅仅采用”每个孩子从下一个元素(index+1)开始”是不够的,因为index之后的元素依然可能重复,因此我们不能让相等元素不能作为兄弟节点,但是可以作为父子。根据这个发现,我们可以先将candidates排序,然后每次搜索时如果本节点和前面的兄弟节点相等,则剪枝。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| List<List<Integer>> res=new ArrayList<>(); int[] candidates; public List<List<Integer>> combinationSum2(int[] candidates, int target) { if (candidates==null)return res; this.candidates=candidates; Arrays.sort(candidates); dfs(target,0,new LinkedList<Integer>()); return res; }
private void dfs(int target, int index, LinkedList<Integer> ans) { if (target==0){ res.add(new ArrayList<>(ans)); return; } for (int i=index;i<candidates.length;i++){ if (i > index && candidates[i] == candidates[i - 1]) { continue; } if (target<candidates[i]) { break; } ans.add(candidates[i]); dfs(target-candidates[i],i+1,ans); ans.removeLast(); } }
|
本人菜鸟,有错误请告知,感激不尽!
更多题解和学习记录博客:博客、github