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 solution in any order.
Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
Input: nums = [0]
Output: [[],[0]]
A subset is any combination of elements (including empty set and full set).
For array [1,2,3], at each position we have 2 choices:
This creates a binary decision tree with 2^n leaf nodes (all subsets).
Key insight: Use backtracking to explore all paths in decision tree.
This is a Backtracking Decision Tree problem:
Template:
def backtrack(start, current):
result.append(current.copy()) # Add current subset
for i in range(start, len(nums)):
current.append(nums[i]) # Choose
backtrack(i + 1, current) # Explore
current.pop() # Unchoose (backtrack)
Why this works:
Start with [[]], for each num, add num to all existing subsets:
[] → add 1 → [[],[1]]
[[],[1]] → add 2 → [[],[1],[2],[1,2]]
Each subset corresponds to a binary number:
Time: O(n × 2^n)
Space: O(n) recursion depth
1import java.util.*;
2
3class Solution {
4 public List<List<Integer>> subsets(int[] nums) {
5 List<List<Integer>> result = new ArrayList<>();
6 backtrack(0, nums, new ArrayList<>(), result);
7 return result;
8 }
9
10 private void backtrack(int start, int[] nums, List<Integer> current, List<List<Integer>> result) {
11 // Add current subset to result
12 result.add(new ArrayList<>(current));
13
14 // Explore adding each remaining element
15 for (int i = start; i < nums.length; i++) {
16 current.add(nums[i]); // Choose
17 backtrack(i + 1, nums, current, result); // Explore
18 current.remove(current.size() - 1); // Unchoose
19 }
20 }
21}
22