Generate All Subsets Powerset in DSA Typescript - Time & Space Complexity
We want to understand how the time needed grows when we find all subsets of a set.
How does the work increase as the input set gets bigger?
Analyze the time complexity of the following code snippet.
function generateSubsets(nums: number[]): number[][] {
const result: number[][] = [];
function backtrack(start: number, subset: number[]) {
result.push([...subset]);
for (let i = start; i < nums.length; i++) {
subset.push(nums[i]);
backtrack(i + 1, subset);
subset.pop();
}
}
backtrack(0, []);
return result;
}
This code finds all subsets (the powerset) of the input array by exploring choices recursively.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls that explore each subset possibility.
- How many times: Each element can be either included or excluded, so about 2n subsets are generated.
As the input size grows, the number of subsets doubles for each new element.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 1,024 subsets |
| 20 | About 1,048,576 subsets |
| 30 | About 1,073,741,824 subsets |
Pattern observation: The work doubles with each added element, growing very fast.
Time Complexity: O(n * 2n)
This means the time grows very fast because we must build all subsets, and each subset can take up to n steps to copy.
[X] Wrong: "Generating all subsets is just O(n) because we just loop through the array once."
[OK] Correct: We actually explore every combination of elements, which grows exponentially, not linearly.
Understanding this exponential growth helps you explain why some problems take longer and shows you can reason about complex recursive solutions.
"What if we only wanted subsets of a fixed size k? How would the time complexity change?"
Practice
powerset mean in the context of sets?Solution
Step 1: Understand the definition of powerset
The powerset of a set is the collection of all subsets, including the empty set and the set itself.Step 2: Compare options with definition
All possible subsets of a given set, including empty and full set correctly describes all subsets, while others describe partial or unrelated sets.Final Answer:
All possible subsets of a given set, including empty and full set -> Option AQuick Check:
powerset = all subsets [OK]
- Thinking powerset excludes empty set
- Confusing powerset with complement set
- Assuming powerset only has subsets of certain size
Solution
Step 1: Analyze the input and output types
The input is an array of numbers, sonums: number[]is correct. The output is all subsets, so an array of arrays of numbersnumber[][]is expected.Step 2: Match options with correct types
function generateSubsets(nums: number[]): number[][] matches input and output types correctly. Others have mismatched types or wrong return types.Final Answer:
function generateSubsets(nums: number[]): number[][] -> Option DQuick Check:
Input array, output array of arrays [OK]
- Returning a flat array instead of array of arrays
- Using wrong input type like number instead of number[]
- Returning a string instead of array
function subsets(nums: number[]): number[][] {
const result: number[][] = [[]];
for (const num of nums) {
const newSubsets = result.map(subset => [...subset, num]);
result.push(...newSubsets);
}
return result;
}
console.log(subsets([1, 2]));Solution
Step 1: Trace the initial state and loop
Start with result = [[]]. For num=1, newSubsets = [[1]], result becomes [[], [1]]. For num=2, newSubsets = [[2], [1, 2]], result becomes [[], [1], [2], [1, 2]].Step 2: Confirm final output
The function returns all subsets: empty, single elements, and full set.Final Answer:
[[], [1], [2], [1, 2]] -> Option AQuick Check:
All subsets of [1,2] listed [OK]
- Forgetting to include empty subset
- Not spreading new subsets correctly
- Returning partial subsets only
function getSubsets(nums: number[]): number[][] {
let result: number[][] = [];
for (const num of nums) {
const newSubsets = result.map(subset => [...subset, num]);
result = [...result, ...newSubsets];
}
return result;
}
console.log(getSubsets([1, 2]));Solution
Step 1: Check initial value of result
The code starts with result = [], missing the empty subset []. This causes no subsets to be generated.Step 2: Understand impact on loop
Since result is empty initially, result.map returns empty array each time, so no subsets are added.Final Answer:
The initial result should contain the empty subset [[]] -> Option CQuick Check:
Start with [[]] to build subsets [OK]
- Starting with empty array instead of array with empty subset
- Misusing map without initial subsets
- Expecting output without base case
nums = [1, 2, 2], which of the following outputs correctly represents all unique subsets (powerset without duplicates) generated by a function that handles duplicates?Solution
Step 1: Understand duplicates in input
The input has duplicate '2's. The powerset must include subsets with one or two '2's but no repeated subsets.Step 2: List all unique subsets
Subsets are: empty [], single elements [1], [2], pairs [1,2], [2,2], and triple [1,2,2]. [[], [1], [2], [1, 2], [2, 2], [1, 2, 2]] lists all correctly without duplicates.Final Answer:
[[], [1], [2], [1, 2], [2, 2], [1, 2, 2]] -> Option BQuick Check:
Include duplicates subsets once [OK]
- Including duplicate subsets multiple times
- Missing subsets with two duplicates
- Adding permutations like [2,1] as separate subset
Ready to prove it?
Pass the test and this pattern moves unknown
