6 of 6
Given an array nums of unique integers, return all possible subsets of nums.
print(subsets([1, 2, 3])) # Output: [[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3]] print(subsets([7])) # Output: [[], [7]] print(subsets([])) # Output: [[]]
For each element, you have two choices:
[]
/ \
[1] []
/ \ / \
[1,2] [1] [2] []
| | | |
[1,2,3] [1,3] [2,3] [3]
For each number, either include it or don't. Build the subset step by step. When you've processed all elements, add the current subset to the result.
def backtrack(path, index, nums, result): if index == len(nums): result.append(path[:]) return # Include nums[index] path.append(nums[index]) backtrack(path, index + 1, nums, result) path.pop() # Exclude nums[index] backtrack(path, index + 1, nums, result)
def subsets(nums): result = [] def backtrack(path, index): if index == len(nums): result.append(path[:]) return # Include nums[index] path.append(nums[index]) backtrack(path, index + 1) path.pop() # Exclude nums[index] backtrack(path, index + 1) backtrack([], 0) return result
Time: O(2^n) β we make 2 choices per element, n elements. Space: O(n) for recursion depth.
def subsets(nums): # Your code here pass # Test your function: print(subsets([1, 2, 3])) # Expected: [[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3]] print(subsets([7])) # Expected: [[], [7]]
Solve it using a for loop instead of the exclude branch. (Iterate from start to end, pick one, recurse with start = i + 1, then backtrack.)
def subsets_loop(nums): result = [] def build(path, start): result.append(path[:]) for i in range(start, len(nums)): path.append(nums[i]) build(path, i + 1) path.pop() build([], 0) return result
Both approaches work β the first is closer to the "choose / don't choose" pattern; the second is often shorter to write!