Subsets

MediumBacktracking · Bit Manipulation🧩 BacktrackingLeetCode #78 ↗Updated

Problem

Given an array nums of distinct integers, return its power set: every possible subset, including the empty set and the full array. No subset may appear twice; the order of subsets (and within them) does not matter.
Input[1,2,3]Output[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
Input[0]Output[[],[0]]

1 ≤ n ≤ 10  ·  -10 ≤ nums[i] ≤ 10  ·  all values distinct

Try it yourself

Java
class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Each element is an independent in / out decision, so there are exactly 2n subsets. Since the output itself has size n · 2n, every approach is output-bound — they differ in how well they extend to constrained / pruned variants.
PatternBacktracking

Instinct Return ALL combinations, permutations, partitions or placements - or ask if any arrangement works - build a candidate step by step and undo each choice.

Memory hack Choose, explore, un-choose - walk the decision tree and snip a branch the moment it can no longer succeed.

Open the Backtracking guide →

Approaches

Brute ForceBitmask Enumeration

Time O(n · 2n)Space O(1) extra

Count mask from 0 to 2n-1; bit i set means nums[i] is in. Every mask is a distinct subset. Each mask scans all n bits, even for tiny subsets.

Java
public List<List<Integer>> subsets(int[] nums) {
    List<List<Integer>> res = new ArrayList<>();
    int n = nums.length;
    for (int mask = 0; mask < (1 << n); mask++) {
        List<Integer> subset = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if ((mask & (1 << i)) != 0) subset.add(nums[i]);
        }
        res.add(subset);
    }
    return res;
}

Mechanical and loop-only, but can't prune and is capped at n ≤ 30 bits.

At a glance

LevelApproachTimeSpace
Brute ForceBitmask EnumerationO(n · 2n)O(1) extra
BetterIterative CascadingO(n · 2n)O(1) extra
OptimalBacktracking (Start Index)O(n · 2n)O(n) extra
Common pitfalls
  • Iterating over res while appending to it — snapshot size first.
  • Recursing with start + 1 instead of i + 1 — produces duplicates.
  • Storing path itself rather than a copy.
Interview tips
  • Say up front: output is n · 2n, so no approach can beat that.
  • Pick backtracking when a follow-up adds constraints (sum target, size k, duplicates).
  • Mention the bitmask view: subsets of n items ↔ integers 0 … 2n-1.
Pattern
Include/exclude backtracking → enumerate all combinations or subsets of a small set.
My notes saved in this browser