Subsets Generation Using Bitmask in DSA Go - Time & Space Complexity
We want to understand how the time needed to generate all subsets grows as the input size increases.
How does the number of operations change when we create subsets using bitmasks?
Analyze the time complexity of the following code snippet.
func subsets(nums []int) [][]int {
n := len(nums)
result := [][]int{}
for mask := 0; mask < (1 << n); mask++ {
subset := []int{}
for i := 0; i < n; i++ {
if mask&(1<
This code generates all subsets of the input list by using bitmasks to decide which elements to include.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Two nested loops - outer loop runs over all bitmasks, inner loop checks each bit.
- How many times: Outer loop runs 2^n times, inner loop runs n times for each outer iteration.
As input size n grows, the number of subsets doubles each time, and for each subset, we check n elements.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 * 2^10 = 10,240 |
| 100 | About 100 * 2^100 (very large) |
| 1000 | About 1000 * 2^1000 (extremely large) |
Pattern observation: The operations grow exponentially with n, doubling for each additional element.
Time Complexity: O(n * 2^n)
This means the time needed grows very fast as input size increases, because we generate all subsets and check each element.
[X] Wrong: "Generating subsets is just O(2^n) because there are 2^n subsets."
[OK] Correct: We also spend time checking each element for every subset, so the inner loop adds a factor of n, making it O(n * 2^n).
Understanding this complexity helps you explain why generating all subsets is expensive and shows your grasp of exponential growth in algorithms.
"What if we used recursion instead of bitmasks to generate subsets? How would the time complexity change?"
Practice
Solution
Step 1: Understand bitmask representation
Each bit in the bitmask represents whether an element is included (1) or excluded (0) in a subset.Step 2: Generate subsets using all bitmasks
By iterating from 0 to 2^n - 1, all combinations of included/excluded elements are covered, producing all subsets.Final Answer:
All possible subsets of the set -> Option CQuick Check:
Bitmask = subsets generator [OK]
- Thinking bitmask generates only specific subsets
- Confusing bitmask with sorting or filtering
- Ignoring subsets with zero elements
Solution
Step 1: Understand bitmask range
For n elements, bitmasks range from 0 to 2^n - 1, which is (1 << n) - 1.Step 2: Correct loop condition
The loop must run from 0 up to but not including (1 << n), so mask < (1 << n) is correct.Final Answer:
for mask := 0; mask < (1 << n); mask++ { } -> Option DQuick Check:
Loop runs 0 to 2^n-1 [OK]
- Using mask <= n instead of mask < (1 << n)
- Starting mask from 1 misses empty subset
- Using mask < n only iterates n times, not 2^n
arr := []int{1, 2}
for mask := 0; mask < (1 << 2); mask++ {
subset := []int{}
for i := 0; i < 2; i++ {
if mask&(1<Solution
Step 1: Understand bitmask values
For n=2, masks go 0 to 3: 0 (00), 1 (01), 2 (10), 3 (11).Step 2: Map bits to subsets
Mask 0: no bits set -> [] Mask 1: bit 0 set -> [1] Mask 2: bit 1 set -> [2] Mask 3: bits 0 and 1 set -> [1, 2]Final Answer:
[ ] [1] [2] [1 2] -> Option AQuick Check:
Bitmask order matches subsets [OK]
- Mixing order of subsets printed
- Confusing which bit corresponds to which element
- Missing empty subset when mask=0
arr := []int{1, 2, 3}
for mask := 0; mask <= (1 << len(arr)); mask++ {
subset := []int{}
for i := 0; i < len(arr); i++ {
if mask&(1<Solution
Step 1: Analyze loop condition
The outer loop runs mask from 0 to (1 << n) inclusive, which is one too many iterations (2^n + 1).Step 2: Correct loop range
It should run from 0 up to but not including (1 << n), so mask < (1 << n) is correct to avoid out-of-range subsets.Final Answer:
Loop condition should be mask < (1 << len(arr)) -> Option AQuick Check:
Loop must run 2^n times exactly [OK]
- Using <= causes one extra invalid iteration
- Confusing & with | for bit checking
- Changing loop indices incorrectly
Solution
Step 1: Understand subsets count by size
Number of subsets of size k from n elements is combination n choose k = C(n, k).Step 2: Calculate C(4, 2)
C(4, 2) = 4! / (2! * (4-2)!) = (4*3)/(2*1) = 6.Final Answer:
6 -> Option BQuick Check:
Number of 2-element subsets = 6 [OK]
- Counting all subsets instead of only size 2
- Using permutations instead of combinations
- Misapplying formula for combinations
Ready to prove it?
Pass the test and this pattern moves unknown
