We need to generate every possible subset of the input array, like the classic Subsets problem (LeetCode #78). The difference here is that the input can contain duplicates, and the result must not include duplicate subsets.
For example, given [1, 2, 2], the subset [1, 2] should appear only once, even though there are two 2s we could pick from. The problem is to generate subsets systematically while skipping choices that would produce a set already built.
Sorting the array first groups duplicates together, which gives a clean way to detect and skip them during generation.
1 <= nums.length <= 10 → With n at most 10, the total number of subsets is at most 2^10 = 1024. An exponential approach is acceptable.-10 <= nums[i] <= 10 → The value range is small relative to the array length, so duplicates are common. A deduplication strategy is needed.Ignore the duplicates entirely, generate all 2^n subsets like the classic Subsets problem, then remove duplicates at the end. Because the array is sorted before generation, two subsets that contain the same values also contain them in the same order, so storing each subset in a set deduplicates them by value.
This adapts a working Subsets solution with minimal changes. It is wasteful, since it generates subsets only to discard them.
Input:
After sorting, nums = [1, 2, 2]. The include/exclude recursion generates all 2^3 = 8 subsets. Listing them in generation order: [1,2,2], [1,2], [1,2], [1], [2,2], [2], [2], []. Two of them repeat: [1,2] appears twice (one 2 picked from each duplicate position) and [2] appears twice. The set keeps one copy of each, leaving 6 unique subsets:
Generating duplicates only to discard them is avoidable. The next approach prunes duplicate branches during generation, so no subset is built twice.
Instead of generating everything and filtering, prevent duplicates from being generated at all. Sort the array so identical values are adjacent, then apply one rule during backtracking: at each decision level, do not pick the same value more than once.
When building subsets by choosing elements from index start onward, we iterate through candidates. If a value matches the previous candidate at the same level (nums[i] == nums[i-1] and i > start), we skip it. The previous candidate already explored every subset that starts with that value from this position, so picking the same value again would regenerate the identical set of subsets.
The condition i > start is what makes the skip safe. When i == start, we pick the first candidate at this level, so the value is always allowed. This is why a subset can still contain multiple copies of the same value (like [2, 2]): consecutive copies are picked at deeper levels where each is the first candidate. The skip only blocks starting a second branch with the same value at the same level, which is exactly the case that produces a duplicate subset.
start = 0.start to n - 1, picking each element as the next addition.i > start and nums[i] == nums[i - 1], skip this element (it would create a duplicate branch).nums[i] to the current subset, recurse with start = i + 1, then remove nums[i] (backtrack).The backtracking approach uses optimal time and linear extra space. The same result can be built iteratively, without recursion.
The iterative approach builds subsets one element at a time. Start with the empty set [[]]. For each new element, take every existing subset and create a new version with the element appended, then add all these new subsets to the result.
Handling duplicates changes one detail. When the current element equals the previous one, we do not extend every existing subset. We extend only the subsets that were added in the previous iteration. Extending the older subsets would recreate the ones already produced when the first occurrence of this value was processed.
Processing the first occurrence of a value extends all existing subsets, creating new subsets that include it. On a duplicate, extending all subsets again would recreate subsets that already exist. The subsets created in the previous step are the only ones not yet extended with this value, so extending only those produces the new combinations without overlap.
Each run of k identical values contributes 0, 1, 2, ..., or k copies of that value to each subset, and this scheme produces exactly one subset for every count in that range.
result = [[]], containing only the empty subset.prevNewCount, which stores how many new subsets were added in the last step.nums[i]:nums[i] == nums[i-1] (duplicate), only extend the last prevNewCount subsets from the result.prevNewCount.