Subsets II

By | August 5, 2016
Share the joy
  •  
  •  
  •  
  •  
  •  
  •  

Given a collection of integers that might contain duplicates, nums, return all possible subsets.

Note: The solution set must not contain duplicate subsets.

For example,
If nums = [1,2,2], a solution is:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

Solution. Let’s first talk about the normal Subset problem, which doesn’t has duplicate. There is a loop way rather than recursion. Let’s say [1, 2, 3]. Assume we already have subset(1, 2), which is {[], [1], [2], [1, 2]}.

For 3, we can either add it {[], [1], [2], [1, 2]}

or not add it {[3], [1, 3], [2, 3], [1, 2, 3]}.

So we will have subset(1, 2, 3), which is {[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]}. It’s like for each element, we can either pick up or not pick up it.

For Subsets II problem, let’s say we want to get subset for [1, 2, 3, 3]. Assume we have subset(1, 2) = {[], [1], [2], [1, 2]}. Based on subset(1, 2), we can either add zero 3, add one 3, or two 3 in the subset(1, 2). So the process is like:

subsetsII2

public static List<List<Integer>> subsetsWithDup(int[] nums) {
    List<List<Integer>> ans = new ArrayList<>(Collections.singleton(new ArrayList<>()));
    Arrays.sort(nums);
    int i = 0;
    while (i < nums.length) {
        int next = i + 1;
        while (next < nums.length && nums[next] == nums[i]) {
            next++;
        }
        int size = ans.size();
        for (int j = 0; j < size; j++) {
            List<Integer> curr = new ArrayList<>(ans.get(j));
            for (int k = 1; k <= next - i; k++) {
                curr.add(nums[i]);
                ans.add(new ArrayList<>(curr));
            }
        }
        i = next;
    }
    return ans;
}

Check my code on github.