Skip to content
AI360Xpert
Beta
Difficulty: MediumBacktracking

Subsets II

Problem in Plain English

Given numbers that may repeat, return every unique subset from the empty set up to the full array. Subsets built from different twin positions count only once.

Problem Statement

Given an integer array nums that may contain duplicates, return every possible subset, including the empty set.

The answer must hold no duplicate subsets: two subsets built from different positions with equal values still count as one.

Return the subsets in any order.

Constraints

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10

Examples

Example 1

Input
nums = [1,2,2]
Output
[[],[1],[1,2],[1,2,2],[2],[2,2]]

There are two choices for the number of 1 values and three choices for the number of 2 values, giving six distinct subsets. The two positions containing 2 do not create two separate [2] answers, but both may be included in [2,2].

Example 2

Input
nums = [0]
Output
[[],[0]]

At the minimum array length, either omit 0 to obtain the empty subset or keep it to obtain [0]. The value zero is an ordinary element; it does not mean an empty subset.

Example 3

Input
nums = [2,-1,2]
Output
[[],[-1],[-1,2],[-1,2,2],[2],[2,2]]

Equal values need not be adjacent in the original input. Sorting brings the two 2 values together; keeping zero, one or two of them, with or without -1, gives six unique subsets. Negative numbers require numeric sorting in JavaScript.

Intuition

A subset chooses how many copies of each value to keep, rather than which equal-valued positions supplied them. In [1,2,2], choose zero or one 1 and zero, one or two 2 values: these choices give six subsets. A position-based search repeats [2] and [1,2]. We can remove those repeats afterward with canonical sorted keys, or sort once and allow only the first equal value to start a branch at each recursion level. Taking the next equal value deeper in that branch still permits [2,2].

Approaches

Enumerate and Dedup

Solution Details

Reveal Enumerate and Dedup: intuition, complexity, and code

Hints

Hint 1
Imagine independently including or excluding each position. Where do [1,2,2] masks produce the same values?
Hint 2
Sorting puts equal values next to each other. Starting two sibling branches with the same value would repeat every extension of that prefix.
Hint 3
Use the guard i > start when comparing a candidate with its predecessor. Record a copy of every path on entry, then recurse at i + 1 and undo the append.

Edge Cases

  • All values equal, such as [2,2,2], give exactly four subsets: [], [2], [2,2], [2,2,2]. Multiplicity must be preserved.
  • An array with no duplicates has all 2n2^n subsets; ten distinct values produce 1024 answers and exercise the maximum output bound.
  • A single [0] yields [[],[0]]; the empty subset and a subset containing zero are different.
  • Unsorted duplicates and negative values, such as [2,-1,2], require canonical ordering before using the adjacent-duplicate rule. All snippets preserve the original input order.
  • Returned subsets own independent lists: editing one answer must not change another answer or the input.

Common Mistakes and Interview Tips

  • Skipping every equal neighbor with i > 0 instead of i > start removes valid multiple-copy subsets such as [2,2].
  • Converting nums to a set erases multiplicity; two copies of 2 are allowed in a subset even though duplicate subsets are forbidden.
  • Appending the mutable path itself instead of copying it makes all DFS answers share storage and change during backtracking.
  • Recursing with start equal to i reuses an input position; recurse at i + 1 and remove the appended value after returning.
  • JavaScript default sort compares strings. Use a numeric comparator, especially for negative numbers; sort a copy when preserving input.
  • Interview tip: distinguish auxiliary space from answer storage, and explain why skipping only equal siblings preserves every possible count of each repeated value.

Key Takeaway

When equal-valued positions represent the same output choice, sort and suppress duplicate sibling branches. Preserve repeated values along deeper branches, snapshot each answer, and undo each temporary choice before exploring another sibling.