Subsets easy
Description
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 answer in any order.
Examples
> Case 1:
nums = [1, 2, 3]
Output: [[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3]]
> Case 2:
nums = [0]
Output: [[], [0]]Constraints
1 <= nums.length <= 10-10 <= nums[i] <= 10- All integers in
numsare unique.
State design
- Partial solution?
pathβ the elements picked so far. - Complete? Once weβve made a decision about every index.
- Choices? Include or skip
nums[i]. - Legality? No constraint β every choice is legal.
- Undo? Pop after recursing into the βincludeβ branch.
The whole power set in 8 lines.
Code β include/skip variant
Alternate code β iterate-over-remaining variant
Every node of the recursion tree IS a subset; we record at every entry instead of only at leaves.
def subsets(nums):
out, path = [], []
def bt(start):
out.append(path[:])
for i in range(start, len(nums)):
path.append(nums[i])
bt(i + 1)
path.pop()
bt(0)
return outBoth are correct. The iterate-over-remaining form is friendlier for follow-ups (subsets with duplicates, combinations, combination sum).
Bonus β bitmask iterative form
For n <= 20, the entire power set fits in 2^n integers. Iterate mask from 0 to 2^n - 1 and read its bits:
def subsets(nums):
n = len(nums)
return [[nums[i] for i in range(n) if mask >> i & 1]
for mask in range(1 << n)]No recursion at all, O(2^n Γ n) time, O(1) aux space. A favorite of competitive programmers.
Analysis
- Time:
O(2^n Γ n)β there are2^nsubsets, each costingO(n)to copy. - Space:
O(n)recursion stack plusO(2^n Γ n)for the output.
Same skin
- Subsets II (input has duplicates) β sort, then in the iterate-over-remaining form skip
nums[i]ifi > start && nums[i] == nums[i - 1]. - Letter Case Permutation β at each character, choose lowercase or uppercase if alphabetic.
- Binary Watch β pick
kof the4 + 6LEDs to be on; subset of size exactlyk.