题意:
给一个无序的,可能有重复的数组。找出其中的数字组合使其之和等于给定数,组合里不能重复使用数组中的某个数,组合之间所包含的值不能相等。
分析:
这个题就是深搜就可以了。但是关键在于如何避免重复:
三个:
第一个
避免两次使用同一个数:每次遍历都从已经放入的数之后
即: for(int i = start; ...;.....){}
第二个,对数组排序,避免组合内容重复
比如 1 2 5 1
如果不排序 1 2 5 . 2 5 1都是合法的搜索,但是内容重复
即Arrays.sort( arr );
第三个,略过重复的数字
比如排好序的 1 1 2 5
任然可能两次 1 2 5 , 1 2 5
即: if (i > start && arr[i] == arr[i-1]) continue;
完整代码:
public class Solution { List<Integer> l = null; List<List<Integer>> list = null; int target; int[] arr; public List<List<Integer>> combinationSum2(int[] candidates, int target) { l = new ArrayList<>(); list = new ArrayList<>(); arr = candidates; Arrays.sort(arr); //2 this.target = target; dfs(0, 0); return list; } private void dfs(int sum, int start){ if(sum >= target){ if(sum==target) list.add(new ArrayList(l)); return; } for(int i=start; i<arr.length; i++){ //1 if (i > start && arr[i] == arr[i-1]) //3 continue; l.add(arr[i]); dfs(sum + arr[i], i+1); l.remove(l.size()-1); } } }