PracticeNeetCode ↗LeetCode ↗
Given a collection of candidate numbers candidates (which may contain duplicates) and a target integer target, find all unique combinations where the numbers sum to target. Each number may be used at most once per combination.
i + 1, not i.i > start and candidates[i] == candidates[i - 1]) prevents identical combinations from being built via different index paths — no need to dedupe the final result afterward.candidates.backtrack(start, remaining): if remaining == 0, record a copy of path.i from start to len(candidates): break if candidates[i] > remaining (sorted, so nothing later fits either).i if i > start and candidates[i] == candidates[i - 1] (avoids duplicate combinations at this level).candidates[i], recurse with backtrack(i + 1, remaining - candidates[i]), then pop.backtrack(0, target) and return the result.Time: O(2ⁿ) worst case — Space: O(n) recursion depth
def combinationSum2(candidates: list[int], target: int) -> list[list[int]]:
candidates.sort()
result = []
path = []
def backtrack(start: int, remaining: int) -> None:
if remaining == 0:
result.append(path[:])
return
for i in range(start, len(candidates)):
if candidates[i] > remaining:
break
if i > start and candidates[i] == candidates[i - 1]:
continue
path.append(candidates[i])
backtrack(i + 1, remaining - candidates[i])
path.pop()
backtrack(0, target)
return resultHow the solution above works, piece by piece.
break once a candidate exceeds remaining.remaining == 0: record the combination.if i > start and candidates[i] == candidates[i - 1]: continue: skip an equal value at the same level, which would only repeat a combination already explored.i + 1: each element is used at most once.The recursion tree for candidates = [10, 1, 2, 7, 6, 1, 5], target = 8:
i + 1), and at each level an equal neighbour is skipped so [1, 2, 5] isn't found twice. Blue leaves are the 4 answers: 1+1+6, 1+2+5, 1+7, 2+6.