DSA Tracker

Medium

Combination Sum II

A medium Backtracking problem included in Love Babbar 450, Striver A2Z. Below: the roles whose interviews prioritise this topic, and how to practise it.

Topic
Backtracking
Sheets
2
Core for
0 roles
Platform
LeetCode

The problem

Given a collection of candidate numbers (which may contain duplicates) and a target number, find all unique combinations where the candidate numbers sum to the target. Each number in the collection may only be used once in each combination.

Example 1

Input
candidates = [10, 1, 2, 7, 6, 1, 5], target = 8
Output
[[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]]
Why
Valid combinations: 1+1+6=8, 1+2+5=8, 1+7=8, 2+6=8. Each number is used at most once per combination.

Example 2

Input
candidates = [2, 5, 2, 1, 2], target = 5
Output
[[1, 2, 2], [5]]
Why
Valid combinations: 1+2+2=5 and 5=5. Duplicate combinations are avoided.

Constraints

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30

How to think about it

Updated 2026-09-09

This combines single-use consumption with duplicate values. Sorting the candidates turns identical values into adjacent runs: taking a duplicate into a deeper recursive call is valid because it consumes a distinct physical element, but initiating a sibling loop branch with an identical value creates a duplicate multiset and must be skipped.

Approaches, worst first

  1. Global set deduplication

    time O(2^n) · space O(n * 2^n)

    Backtrack using index + 1 on each step to enforce single-use, but use a hash set of tuples to discard duplicate combinations at completion. Wastes time exploring duplicate subtrees and exceeds time limits on inputs with many repeated small integers.

  2. Sorted backtracking with sibling skipWrite this one

    time O(2^n) · space O(n)

    Sort candidates first. At recursion depth startIndex, iterate i from startIndex to n. If i > startIndex and candidates[i] == candidates[i - 1], skip i. If candidates[i] > target, break early. Advance to i + 1 for subsequent choices to enforce single use.

Where people lose marks · 3
  • Confusing i > startIndex with i > 0. Checking i > 0 prevents picking duplicate values that appear at different positions in the combination, wrongly dropping combinations like [1, 1, 6].
  • Passing startIndex + 1 into the recursive call instead of i + 1, causing infinite loops or illegal repeated selections of earlier items.
  • Continuing the loop instead of breaking when candidates[i] exceeds the remaining sum. Because candidates are sorted, every subsequent candidate will also exceed target.

The theory behind it

Backtracking — the ground this problem stands on. All Backtracking problems

What Backtracking is

Backtracking is an organized trial-and-error search through a maze of possibilities. You make a tentative choice, move forward to explore where that path leads, and if you hit a dead end or finish finding an answer, you back up and undo that choice. By cleaning up your changes before trying the next option, a single shared board or list is explored thoroughly without needing to clone full copies of your data at every turn.

When to reach for it

Reach for backtracking when a problem asks to generate all possible solutions, like all subsets, permutations, valid parentheses combinations, or word search paths on a board. Signals include puzzles with strict constraint rules, like placing eight non-attacking queens on a chessboard or solving a Sudoku grid. Whenever you must construct combinations step by step and abandon dead-end branches early before wasting time exploring impossible paths, use backtracking.

How the pattern works

Follow a three-step rhythm inside a loop: choose, explore, and unchoose. First, check if the current state satisfies your goal; if so, save a copy of it and return. Next, prune illegal moves immediately using constraint checks so unpromising branches are skipped. For each valid candidate, apply the move to your shared path or board, call the recursive function to explore deeper, and finally undo the move right after the call returns. Undoing restores the shared state so sibling choices start from a clean slate.

What each operation costs

OperationTime
generate all subsets of n elementsO(2^n)
generate all permutations of n elementsO(n!)
auxiliary recursion stack memory depthO(n)
What usually goes wrong with Backtracking
  • Adding a mutable path list directly to the final answers collection without creating a shallow copy, leaving every saved result empty once backtracking finishes.
  • Forgetting to undo a state change after the recursive call returns, contaminating subsequent branches with leftover moves from earlier paths.
  • Generating duplicate subsets or permutations by failing to sort the input array and skip adjacent identical elements during branch selection.

Track this in your role's order

Pick your target role and all 370 problems — including this one — resequence to what that interview actually asks. Free.

Start free

More Backtracking problems

Problem set and role mapping as of .