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;
}
}