Given a collection of integers that might contain duplicates, S, return all possible subsets.
Note:
- Elements in a subset must be in non-descending order.
- The solution set must not contain duplicate subsets.
For example,
If S = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
A shorter solution:
public class Solution { public List<List<Integer>> subsetsWithDup(int[] num) { Arrays.sort(num); int length = num.length; List<List<Integer> > result = new ArrayList<List<Integer>>(); List<Integer> aSubset = new ArrayList<Integer>(); result.add(aSubset); int size = 1; int i = 0; while(i < length){ int mult = 0; int current = num[i]; while(i < length){ if(current != num[i]) break; else{ ++i; ++mult; } } for(int k = 0; k < mult; ++k){ for(int j = 0; j < size; ++j){ List<Integer> newList = new ArrayList<Integer>(); newList.addAll(result.get(k*size + j)); newList.add(current); result.add(newList); } } size *= (mult + 1); } return result; } }
Another solution:
public class Solution { public ArrayList<ArrayList<Integer> > subsetsWithDup(int[] num){ Arrays.sort(num); HashMap<Integer, Integer> mult = new HashMap<Integer, Integer>(); HashMap<Integer, Integer> dist = new HashMap<Integer, Integer>(); int l = 0; for(int i = 0; i < num.length; ++i){ if(mult.containsKey(num[i])){ int mu = mult.get(num[i]); mult.put(num[i], ++mu); } else{ mult.put(num[i], 1); dist.put(l, num[i]); ++l; } } ArrayList<ArrayList<Integer> > result = new ArrayList<ArrayList<Integer> >(); int nums = (int)Math.pow(2, l); for(int i = 0; i < nums; ++i){ ArrayList<ArrayList<Integer> > list = new ArrayList<ArrayList<Integer> >(); list.add(new ArrayList<Integer>()); String binaryreps = Integer.toBinaryString(i); int length = binaryreps.length(); for(int j = 0; j < length; ++j){ ArrayList<ArrayList<Integer> > temp = new ArrayList<ArrayList<Integer> >(); if(binaryreps.charAt(length - 1 - j) == '1'){ while(!list.isEmpty()){ ArrayList<Integer> aList = list.remove(0); int times = mult.get(dist.get(j)); for(int m = 1; m <= times; ++m){ ArrayList<Integer> newList = new ArrayList<Integer>(); newList.addAll(aList); for(int n = 1; n <= m; ++n) newList.add(dist.get(j)); temp.add(newList); } } list = temp; } } result.addAll(list); } return result; } }