90. Subsets II
Description
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 1:
Input: nums = [1,2,2] Output: [[],[1],[1,2],[1,2,2],[2],[2,2]]
Example 2:
Input: nums = [0] Output: [[],[0]]
Constraints:
1 <= nums.length <= 10-10 <= nums[i] <= 10
Solutions
Solution 1: Sorting + DFS
Thinking
The first idea is the same DFS as Subsets: take or skip each index. Correct, but duplicates make \([1, 2]\) appear twice. \(n \le 10\) is small, yet the solution set must be unique.
The bottleneck is treating equal values at different indices as distinct choices. Sort so equals sit together; skip the same value on the “not take” branch so each multiset is generated once.
After sorting, DFS: take \(i\), then on the skip path jump over every later equal \(\textit{nums}[i]\). How many copies we take is decided by recursion depth, never as two identical subsets side by side.
We can first sort the array \(\textit{nums}\) to facilitate deduplication.
Then, we design a function \(\textit{dfs}(i)\), which represents the current search for subsets starting from the \(i\)-th element. The execution logic of the function \(\textit{dfs}(i)\) is as follows:
If \(i \geq n\), it means all elements have been searched, add the current subset to the answer array, and end the recursion.
If \(i < n\), add the \(i\)-th element to the subset, execute \(\textit{dfs}(i + 1)\), then remove the \(i\)-th element from the subset. Next, we check if the \(i\)-th element is the same as the next element. If they are the same, skip the element in a loop until we find the first element different from the \(i\)-th element, then execute \(\textit{dfs}(i + 1)\).
Finally, we only need to call \(\textit{dfs}(0)\) and return the answer array.
The time complexity is \(O(n \times 2^n)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array \(\textit{nums}\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
Solution 2: Sorting + Binary Enumeration
Thinking
Solution 1 already deduplicates, but recursion pays a stack and the skip logic is easy to get wrong. \(n \le 10\), so we can enumerate all \(2^n\) masks.
What it lacks is “take or skip” as bits. Bit \(i\) of \(\textit{mask}\) means taking \(\textit{nums}[i]\); taking \(i\) without \(i - 1\) when the values are equal skips an earlier copy — a duplicate, drop it. Same asymptotics, one loop.
Similar to Solution 1, we first sort the array \(\textit{nums}\) to facilitate deduplication.
Next, we enumerate a binary number \(\textit{mask}\) in the range \([0, 2^n)\), where the binary representation of \(\textit{mask}\) is an \(n\)-bit bit string. If the \(i\)-th bit of \(\textit{mask}\) is \(1\), it means selecting \(\textit{nums}[i]\), and \(0\) means not selecting \(\textit{nums}[i]\). Note that if the \((i - 1)\)-th bit of \(\textit{mask}\) is \(0\) and \(\textit{nums}[i] = \textit{nums}[i - 1]\), it means that the \(i\)-th element is the same as the \((i - 1)\)-th element in the current enumeration scheme. To avoid duplication, we skip this case. Otherwise, we add the subset corresponding to \(\textit{mask}\) to the answer array.
After the enumeration, we return the answer array.
The time complexity is \(O(n \times 2^n)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array \(\textit{nums}\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |