const solve = (nums) => { let left = 0, right = nums.length - 1; while (left < right) { const sum = nums[left] + nums[right]; if (sum === target) return [left, right]; }}
Problem Walkthrough

Subsets LeetCode Solution: Three Approaches to #78

Subsets (#78) is the simplest backtracking problem on LeetCode — and the foundation of every "generate all" problem you will encounter in coding interviews.

8 min read|

Subsets (#78): include or exclude — the simplest backtracking

Three approaches to the power set: backtracking, iterative, and bit manipulation

Subsets: The Foundation of Backtracking

Subsets leetcode problem #78 is the first backtracking problem most engineers encounter on the NeetCode roadmap, and for good reason. It strips away all the complexity of more advanced backtracking problems and gives you the purest version of the core decision: for each element, do you include it or skip it?

Once you internalize this include-or-exclude pattern, problems like Permutations (#46), Combination Sum (#39), and Subsets II (#90) become variations on the same theme rather than entirely new challenges. That is why mastering this single problem unlocks an entire category of interview questions.

In this walkthrough, we will cover three distinct approaches to generating the power set: backtracking with recursion, an iterative build-up method, and a bit manipulation technique that maps subsets to binary numbers. Each approach runs in O(n * 2^n) time, but they exercise different problem-solving muscles that interviewers value.

Understanding the Subsets Problem

The problem statement is straightforward: given an integer array nums of unique elements, return all possible subsets (the power set). The solution set must not contain duplicate subsets, and you can return the answer in any order.

For example, given nums = [1, 2, 3], the output is [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]. That is 2^3 = 8 subsets in total. For an array of n distinct elements, there are always exactly 2^n subsets because each element is either included or excluded.

This is exactly the definition of the power set from discrete mathematics. The key insight is that the number of subsets grows exponentially with the input size, so any correct solution must be at least O(2^n) — there is no shortcut around generating all of them.

  • Input: an array of distinct integers (constraint: 1 <= nums.length <= 10)
  • Output: a list of all possible subsets, including the empty set
  • No duplicate subsets allowed in the result
  • Order of subsets and elements within subsets does not matter
ℹ️

Why This Problem Matters

Subsets (#78) is the first backtracking problem in the NeetCode roadmap — it teaches the include/exclude decision tree that powers Permutations, Combination Sum, and every 'generate all' problem.

Subsets Backtracking Approach

The backtracking approach models the problem as a binary decision tree. At each level of the tree, you decide whether to include or exclude the current element. When you have made a decision for every element, you have reached a leaf node — a complete subset.

You start with an empty current subset and an index pointing to the first element. At each recursive call, you add the current state to your result (every node in the tree represents a valid subset, not just leaves). Then you loop from the current index forward, adding each element to your subset, recursing deeper, and then removing the element (backtracking) to explore the next branch.

The time complexity is O(n * 2^n) because there are 2^n subsets and copying each subset into the result takes O(n) time. The space complexity is O(n) for the recursion stack depth, not counting the output storage.

  1. 1Initialize an empty result list and an empty current subset
  2. 2Define a recursive function that takes the current index
  3. 3At each call, add a copy of the current subset to the result
  4. 4Loop from the current index to the end of nums
  5. 5Add nums[i] to the current subset and recurse with index i + 1
  6. 6Remove the last element (backtrack) before the next iteration

Subsets Iterative Approach

The iterative approach is arguably the most elegant solution to the subsets leetcode problem. You start with a result containing only the empty subset: [[]]. Then for each number in the input array, you take every existing subset in the result, make a copy with the new number appended, and add all those new subsets back to the result.

For nums = [1, 2, 3], the process unfolds like this. Start with [[]]. Process 1: copy [] and add 1 to get [1], result is now [[], [1]]. Process 2: copy [] and [1], add 2 to each to get [2] and [1,2], result is now [[], [1], [2], [1,2]]. Process 3: copy all four and add 3, result is the complete power set with 8 subsets.

This approach has the same O(n * 2^n) time complexity as backtracking, but it avoids recursion entirely. The space complexity is O(1) beyond the output itself, making it slightly more memory-efficient. Many engineers find this approach easier to implement correctly under interview pressure because there is no recursive state to manage.

💡

Pro Tip

The iterative approach is the most intuitive: start with [[]], and for each new number, copy all existing subsets and add the number to each copy. No recursion needed.

Subsets Bit Manipulation Approach

The bit manipulation approach exploits a direct mapping between subsets and binary numbers. For an array of n elements, every integer from 0 to 2^n - 1 can be represented as an n-bit binary number. Each bit position corresponds to an element in the array: if the bit is 1, include that element; if 0, exclude it.

For nums = [1, 2, 3], the binary number 101 (which is 5 in decimal) maps to the subset [1, 3] because the first and third bits are set. The number 000 maps to the empty set, and 111 maps to [1, 2, 3]. You simply iterate from 0 to 2^n - 1 and construct each subset by checking which bits are set.

This approach also runs in O(n * 2^n) time. It is particularly elegant for interviews because the implementation is concise and demonstrates comfort with bitwise operations. However, it only works when n is small enough that 2^n fits in an integer — which is always the case for this problem given the constraint n <= 10.

  1. 1Calculate totalSubsets = 2^n using bit shift: 1 << n
  2. 2Loop mask from 0 to totalSubsets - 1
  3. 3For each mask, loop through each bit position j from 0 to n - 1
  4. 4If bit j is set in mask (mask & (1 << j) is nonzero), include nums[j]
  5. 5Add the constructed subset to the result

Edge Cases and Subsets II

The edge cases for subsets leetcode #78 are minimal but worth knowing. An empty array returns [[]]. A single-element array [x] returns [[], [x]]. Since the problem guarantees distinct elements, you never need to worry about deduplication in the basic version.

The natural follow-up is Subsets II (#90), where the input array can contain duplicates. For example, [1, 2, 2] should produce [[], [1], [2], [1,2], [2,2], [1,2,2]] — notice there is only one [2], not two. The trick is to sort the array first and then skip duplicates at the same decision level during backtracking, the same technique used in 3Sum and Combination Sum II.

In interviews, expect the interviewer to ask about Subsets II as a follow-up after you solve #78. Having the sort-and-skip pattern ready shows depth of understanding beyond memorized solutions.

⚠️

Watch Out

Subsets II (#90) adds duplicate elements — you need to sort first and skip duplicates at the same decision level, exactly like 3Sum. Don't attempt #90 until you've mastered #78.

What the Subsets Problem Teaches You

The include/exclude decision pattern from subsets is the backbone of nearly every backtracking and recursive enumeration problem on LeetCode. Once you see that Permutations is "choose which unused element goes next" and Combination Sum is "include this candidate again or move on," you realize they are all variations of the same binary choice tree.

Practicing subsets also builds your intuition for exponential time complexity. When you see 2^n in a problem constraint (like n <= 20), it is a strong hint that the intended solution enumerates all subsets or uses bitmask DP. Recognizing this signal saves you from overcomplicating the approach.

If you are preparing for coding interviews, make this problem your first stop in the backtracking category. Solve it with all three approaches, understand why each works, and then move on to Subsets II, Permutations, and Combination Sum. YeetCode flashcards can help you drill the include/exclude pattern through spaced repetition so it becomes automatic during your interview.

  • Include/exclude is the fundamental backtracking decision
  • Subsets unlocks Permutations (#46), Combination Sum (#39), and Letter Combinations (#17)
  • Exponential output means O(2^n) is unavoidable — focus on clean implementation
  • Three approaches (backtracking, iterative, bit manipulation) test different skills
  • Sort-and-skip for duplicates extends naturally to Subsets II and Combination Sum II

Ready to master algorithm patterns?

YeetCode flashcards help you build pattern recognition through active recall and spaced repetition.

Start practicing now