Combination Sum
Given distinct candidates and a target, return every unique combination that sums to target. The same number may be reused unlimited times.
Intuition
Build combinations by repeatedly choosing a candidate. To avoid duplicate combinations in a different order, only ever pick candidates from the current index onward — that fixes a non-decreasing order.
Approach
Blind enumeration explodes and duplicates
Generating every possible multiset of candidates and filtering those summing to the target is hopeless: the search space is huge, and it produces the same combination in many orders ([2,2,3], [2,3,2], [3,2,2]). Both problems are solved by structuring the search as a recursion that only ever extends combinations in one direction.
Recurse with a start index and a shrinking target
Backtracking explores choices one at a time. Pass a start index and a remaining target down the recursion. At each level you may pick candidates[i] for any i >= start, subtract it from remain, and recurse. The key to allowing reuse is recursing with the same index i (not i + 1), so the same number can be chosen repeatedly. Forcing choices to move forward from start is also what prevents reordered duplicates — combinations are always built in non-decreasing index order.
Base case, pruning, and undo
When remain hits exactly 0, we've found a valid combination — append a copy of the current path (not the live list, which keeps mutating). Prune any branch where a candidate exceeds remain, since it can't lead anywhere. After each recursive call, pop the last choice to backtrack and try the next — that undo is what lets one path object explore the whole tree. Roughly O(N^(target/min)) in the worst case.
Solution & live demo
Edge cases
The remain - c >= 0 guard skips it, so it never enters a combination.
Each distinct multiset is found once because choices only move forward from start.
Recursing with the same start index permits unlimited reuse, e.g. [2,2,3] for target 7.