Given a set of distinct integers, 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,3], a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
Thoughts
Comparing this problem with Subsets can help better understand the problem.
Java Solution
public ArrayList<ArrayList<Integer>> subsetsWithDup(int[] num) { if (num == null) return null; Arrays.sort(num); ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); ArrayList<ArrayList<Integer>> prev = new ArrayList<ArrayList<Integer>>(); for (int i = num.length-1; i >= 0; i--) { //get existing sets if (i == num.length - 1 || num[i] != num[i + 1] || prev.size() == 0) { prev = new ArrayList<ArrayList<Integer>>(); for (int j = 0; j < result.size(); j++) { prev.add(new ArrayList<Integer>(result.get(j))); } } //add current number to each element of the set for (ArrayList<Integer> temp : prev) { temp.add(0, num[i]); } //add each single number as a set, only if current element is different with previous if (i == num.length - 1 || num[i] != num[i + 1]) { ArrayList<Integer> temp = new ArrayList<Integer>(); temp.add(num[i]); prev.add(temp); } //add all set created in this iteration for (ArrayList<Integer> temp : prev) { result.add(new ArrayList<Integer>(temp)); } } //add empty set result.add(new ArrayList<Integer>()); return result; } |
Feed the method [1,2,3] the following will be result at each iteration.
[2] [2][2,2] [2][2,2][1,2][1,2,2][1] Get [] finally.
I think this video has a very simple solution
https://www.youtube.com/watch?v=XtJ-dpLmK4Y
This solution is for array contains duplicates numbers:
“Given a collection of integers that might contain duplicates, nums, return all possible subsets.”
public static void subsets(int[] arr){
for(int i=1; i <= arr.length; i++){
ps(arr, i, 0);
}
}
public static void print(int[] arr, int e){
for(int i=0; i<=e; i++){
System.out.print(" "+ arr[i]);
}
System.out.println("");
}
public static void ps(int[] arr, int length, int s){
for(int j = length-1; j < arr.length; j++){
swap(arr,length-1, j);
print(arr, length-1);
swap(arr,length-1, j);
}
}
public static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
Its kind of easier if ArrayList apis are allowed. Whenever you modify the result just check if the list exist in the result.
public List<List> subsetsWithDup(int[] nums) {
List<List> result = new ArrayList<List>();
result.add(new ArrayList());
Arrays.sort(nums);
for (int i = 0; i < nums.length; i ++) {
int curSize = result.size();
for (int j = 0; j < curSize; j ++) {
List cur = new ArrayList(result.get(j));
cur.add(nums[i]);
if(!result.contains(cur))
result.add(cur);
}
}
return result;
}
Hey What exactly is difference between the 2 questions subset and subset II ?? Both the questions are exactly the same.
Hi,
Why I can’t use ” result.addAll(prev); ” as what you did in Subsets?
Thanks,