https://leetcode.com/problems/subsets-ii/
Given a collection of integers that might contain duplicates, S, return all possible subsets.
Note:
For example,
If S = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
解题思路:
和上题不同,这里有了重复元素,就多了很多可能,因为[1,2]和[1,2,2]是不同的。
这里用的也是很重要的去重思路,如果和前一个元素相同,就跳过,不DFS。否则会出现下面的错误。
Input: | [1,1] |
Output: | [[1],[1,1],[1],[]] |
Expected: | [[],[1],[1,1]] |
这个思路其实和前面很多思路都很像,包括Combination Sum II、比如Search in Rotated Sorted Array II,比如3Sum等。
public class Solution { public List<List<Integer>> subsetsWithDup(int[] num) { List<List<Integer>> result = new LinkedList<List<Integer>>(); List<Integer> current = new LinkedList<Integer>(); Arrays.sort(num); dfs(result, current, num, 0); result.add(new LinkedList<Integer>()); return result; } public void dfs(List<List<Integer>> result, List<Integer> current, int[] S, int step){ if(step == S.length){ return; } for(int i = step; i < S.length; i++){ //这也是去重的重要方法 if(i > step && S[i] == S[i - 1]){ continue; } current.add(S[i]); result.add(new LinkedList(current)); dfs(result, current, S, i + 1); current.remove(current.size() - 1); } } }
这道题的去重也可以用set来做。原来以为List的equals()方法比较的也是地址,并不是内容,会出现Object无法比较==的情况。但是后来发现List已经重写了自己的equals()方法,回去比较每一个元素。但是要耗费额外的空间,时间也多,思路上也不如上面的方法来的漂亮。
public class Solution { public List<List<Integer>> subsetsWithDup(int[] num) { List<List<Integer>> result = new LinkedList<List<Integer>>(); List<Integer> current = new LinkedList<Integer>(); Set<List<Integer>> set = new HashSet<List<Integer>>(); Arrays.sort(num); dfs(result, current, num, 0, set); result.add(new LinkedList<Integer>()); return result; } public void dfs(List<List<Integer>> result, List<Integer> current, int[] S, int step, Set<List<Integer>> set){ if(step == S.length){ return; } for(int i = step; i < S.length; i++){ current.add(S[i]); if(!set.contains(current)){ set.add(current); result.add(new LinkedList(current)); dfs(result, current, S, i + 1, set); } current.remove(current.size() - 1); } } }