Subsets
Given an integer array nums of unique elements, return all possible subsets (the power set). The solution set must not contain duplicate subsets. Return the solution in any order.
Subsets (Power Set)
Problem Statement
You are given an integer array, nums, with all unique elements. Return all possible subsets of nums — this is also called the power set.
The solution set must not contain any duplicate subsets. You can return the subsets in any order.
Examples
Example 1
Input: nums = [1, 2, 3]
Output: [[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3]]
Example 2
Input: nums = [0]
Output: [[], [0]]
Constraints
1 ≤ nums.length ≤ 10−10 ≤ nums[i] ≤ 10- All the numbers in
numsare unique.
Solution
This solution uses a neat trick with binary numbers (bitmasking).
The Main Idea
- If
numshasnelements, there are exactly2ⁿpossible subsets. This is because for each element, we have two choices: include it or don't include it. - We can represent every possible subset using a number from
0to2ⁿ - 1, written in binary. Each bit in this number tells us whether to include the element at that position.
For example, if nums = [1, 2, 3] and we look at the number 2, which is 010 in binary:
- The rightmost bit (position 0) is
0→ don't includenums[0]. - The middle bit (position 1) is
1→ includenums[1]. - The leftmost bit (position 2) is
0→ don't includenums[2].
So the number 2 (binary 010) represents the subset [2] (since nums[1] = 2).
Steps
- We loop through every number
ifrom0to2ⁿ - 1. Each of these numbers represents one possible subset. - For each number
i, we check every bit positionj(from0tonums.length - 1):- We use a helper function,
getBit(num, bit), to check if the bit at positionjis1or0. - If the bit is
1, we includenums[j]in the current subset.
- We use a helper function,
- Once we've checked all bit positions for a given
i, we've built one full subset. We add it to our results. - We repeat this for every number from
0to2ⁿ - 1, which gives us every possible subset.
How getBit Works
The getBit function checks whether a specific bit position in a number is 1 or 0:
- It shifts the number
1to the left bybitpositions. This creates a number with a single1at exactly the position we want to check. - It then performs an AND operation between this shifted number and our original number.
- If the result is not zero, that bit position is
1. Otherwise, it's0.
Code
function getBit(num, bit) {
let temp;
temp = 1 << bit;
temp = temp & num;
if (temp === 0) {
return 0;
}
return 1;
}
function findAllSubsets(nums) {
let sets = [];
if (nums.length === 0) {
return [[]];
} else {
let subsetsCount = 2 ** nums.length;
for (let i = 0; i < subsetsCount; i++) {
let subset = new Set();
for (let j = 0; j < nums.length; j++) {
if (getBit(i, j) == 1 && !subset.has(nums[j])) {
subset.add(nums[j]);
}
}
if (i === 0) {
sets.push([]);
} else {
sets.push(Array.from(subset));
}
}
}
return sets;
}