The “Subsets” problem is a classic example of combinatorial generation. Given an array of distinct integers, the task is to return all possible subsets (also known as the power set). This includes the empty subset and the full array itself.
For instance, given the input [1, 2, 3]
, the output should be [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]
. The number of subsets for an array of length n is 2ⁿ
, since each element can either be included or excluded from a subset.
The most intuitive and scalable way to generate all subsets is through backtracking. This recursive method explores every decision point: whether to include or exclude the current element. For each index in the input array, we branch into two paths—one that includes the element and one that skips it.
A temporary list (commonly named sol
) is used to build the current subset, and another list ans
collects all valid subsets. At every recursive call, once we reach the end of the input array, we add a copy of sol
to ans
. This ensures that each possible combination is explored and recorded.
This algorithm has a time complexity of O(2ⁿ × n), where n is the length of the input array. The 2ⁿ factor comes from the number of possible subsets, and the extra n factor comes from the cost of copying subsets.
The space complexity is also O(2ⁿ × n) to store the final list of subsets. The recursion depth reaches up to n, and the call stack uses O(n) space.
An iterative solution is also possible: start with [[]]
, and for each number in the input array, iterate through the existing subsets and append a new subset that includes the current number. This approach avoids recursion but builds the power set in a similar way.
The “Subsets” problem is foundational for understanding recursion, backtracking, and binary decision trees in combinatorics. It's a great stepping stone for more advanced problems involving permutations, combinations, and subset sums.