THN Interview Prep

39. Combination Sum

At a Glance

  • Topic: backtracking
  • Pattern: DFS / Backtracking
  • Difficulty: Medium
  • Companies: Amazon, Google, Meta, Microsoft, Bloomberg
  • Frequency: Very High
  • LeetCode: 39

Problem (one-liner)

Given distinct positive candidates and target, return all unique combinations that sum to target. The same number may be reused unlimited times.

Recognition Cues

  • Sum exactly target with reuse
  • Combinations not permutations — enforce non-decreasing index order in DFS
  • Positive integers → bounded recursion

Diagram

At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.

Loading diagram…

Approaches

  • Brute — generate multisets — exponential waste.
  • Optimal — DFS with start index, prune when sum > target — O(2^target) worst conceptual; tight in practice with pruning.

Optimal Solution

Go

func combinationSum(candidates []int, target int) [][]int {
	result := [][]int{}
	path := make([]int, 0, 16)

	var dfs func(start int, remaining int)
	dfs = func(start int, remaining int) {
		if remaining == 0 {
			copied := make([]int, len(path))
			copy(copied, path)
			result = append(result, copied)
			return
		}
		if remaining < 0 {
			return
		}
		for index := start; index < len(candidates); index++ {
			value := candidates[index]
			path = append(path, value)
			dfs(index, remaining-value)
			path = path[:len(path)-1]
		}
	}
	dfs(0, target)
	return result
}

JavaScript

function combinationSum(candidates, target) {
  const result = [];
  const path = [];

  function dfs(startIndex, remaining) {
    if (remaining === 0) {
      result.push([...path]);
      return;
    }
    if (remaining < 0) {
      return;
    }
    for (let index = startIndex; index < candidates.length; index += 1) {
      path.push(candidates[index]);
      dfs(index, remaining - candidates[index]);
      path.pop();
    }
  }

  dfs(0, target);
  return result;
}

Walkthrough

candidates = [2,3,6,7], target = 7. Paths: [7], [2,2,3].

Invariant: Loop starts at start so [2,3] and [3,2] are not both generated.

Edge Cases

  • Exact hit with single coin
  • No solution → empty list
  • Large target with small coins — depth bounded by target/min

Pitfalls

  • Advancing start by index+1 — that forbids reuse (wrong for this problem)
  • Not copying path when recording answer

Similar Problems

Variants

  • Coin count limit — cap how many times each value may be used.
  • Negative candidates — sort + prune; watch for non-termination.

Mind-Map Tags

#backtracking #combination #dfs #reuse-allowed #sorted-start-index

Last updated on

Spotted something unclear or wrong on this page?

On this page