Finding all the subsets of a set
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Generating every subset of a set, also called the power set, is a common building block in combinatorics, brute-force search, and feature selection. The core algorithms are straightforward, but the real constraint is exponential growth: a set with n elements has 2^n subsets, so the output size dominates everything else.
Understand the Size Before Choosing an Algorithm
For small inputs, almost any correct method is fine. For larger inputs, the number of subsets explodes quickly:
n = 10produces 1024 subsetsn = 20produces 1,048,576 subsets
That means no implementation can be “fast” in the usual sense once the input grows. The best you can do is choose a clear method, avoid unnecessary overhead, and generate lazily when possible.
Iterative Doubling Is Simple and Readable
A clean iterative method starts with the empty subset and, for each item, adds a copy of every existing subset with that item included.
This version is excellent for teaching and for small-to-medium inputs where clarity matters most.
Bitmask Generation Is Compact and Deterministic
Each subset can be represented by a bitmask where each bit says whether the corresponding item is present.
Bitmasks are convenient when you also need numeric representations for search or caching. They also guarantee a stable ordering based on mask order.
Recursive Backtracking Is Easy To Extend
Backtracking is another common solution. At each position, decide whether to include the current element, then recurse to the next position.
This style is especially useful when you later want to add pruning rules, subset-size limits, or constraints on valid combinations.
Generate Lazily When You Do Not Need Everything at Once
If the consumer can process subsets one by one, a generator reduces peak memory use dramatically.
This does not change the total amount of work, but it keeps you from storing the whole power set in memory at the same time.
Generate Only the Subsets You Actually Need
Many real tasks do not need every subset. If you only need subsets of size k, use a constrained generator such as itertools.combinations.
This is often the difference between a practical solution and an accidental exponential blow-up.
Validate Count and Ordering Assumptions
Different algorithms produce subsets in different orders. If another part of the program depends on output order, define that contract explicitly and test it. At a minimum, verify the count and a few key members.
These checks are simple but catch many refactoring mistakes.
Common Pitfalls
The biggest mistake is ignoring exponential growth and exposing subset generation without input limits. Another is assuming all algorithms produce subsets in the same order. Developers also generate a full power set when they only need fixed-size combinations, which wastes both time and memory.
Summary
- Power-set generation is inherently exponential because the output size is
2^n. - Iterative doubling, bitmasks, and backtracking are all valid core techniques.
- Use lazy generation when the consumer does not need all subsets at once.
- Prefer constrained methods such as combinations when only fixed-size subsets are required.
- Define output-order expectations and add input-size limits for production use.

