Subsets II
Explain the Problem
Given an integer array nums
that may contain duplicates, return all possible subsets (the power set). The solution set must not contain duplicate subsets. Return the solution in any order.
Example:
Input: nums = [1,2,2]
Output:
[
[],
[1],
[1,2],
[1,2,2],
[2],
[2,2]
]
1) Explain the problem
Given an integer array nums
that may contain duplicates, return all possible subsets (the power set). The solution set must not contain duplicate subsets.
2) Short easy to remember solution/approach
Use backtracking to generate all possible subsets.
Sort the array to handle duplicates easily.
Use a set to avoid adding duplicate subsets.
3) Solution in JavaScript with code commenting
function subsetsWithDup(nums) {
const result = [];
nums.sort((a, b) => a - b); // Sort to handle duplicates easily
function backtrack(start, currentSubset) {
result.push([...currentSubset]);
for (let i = start; i < nums.length; i++) {
if (i > start && nums[i] === nums[i - 1]) continue; // Skip duplicates
currentSubset.push(nums[i]);
backtrack(i + 1, currentSubset);
currentSubset.pop(); // Backtrack to try the next number
}
}
backtrack(0, []);
return result;
}
// Example usage:
const nums = [1, 2, 2];
console.log(subsetsWithDup(nums));
// Output: [[], [1], [1, 2], [1, 2, 2], [2], [2, 2]]
4) Explanation the solution in an easy-to-understand way with real-life example
Imagine you have a bag of numbers, and some of them might be the same. You want to find all possible groups you can make with these numbers, including the empty group. For example, if your numbers are [1, 2, 2], you can make groups like [], [1], [2], [1, 2], [2, 2], and [1, 2, 2].
5) Code explanation in pointers
Sort the array: Sort the array to make it easier to handle duplicates.
Initialize result array: This array will store all unique subsets.
Backtracking function: This function generates all possible subsets starting from a given index.
Add current subset: Add the current subset to the result.
Loop through numbers: From the current index to the end of the array.
Skip duplicates: If the current number is the same as the previous one and not the start of the loop, skip it.
Recursive call: Add the current number to the subset and recurse to generate further subsets.
Backtrack: Remove the last number from the subset to try the next possibility.
Return result: After exploring all possibilities, return the result array.
6) Complexities
Time complexity: (O(2^n)) where (n) is the number of elements in the array. This is because each element can either be included or not in each subset.
Space complexity: (O(n \cdot 2^n)) for storing all the subsets and the recursion stack.
Subscribe to my newsletter
Read articles from Abhi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by