We're given an array of numbers that may contain duplicates, and we need to find all unique combinations that add up to a target sum. Each element in the array can be used at most once (based on its position), and we can't have duplicate combinations in the result.
Two requirements interact here. The search must explore subsets that sum to a target, and the input can contain duplicate values, so naive backtracking produces the same combination through different index paths. For example, with candidates = [1, 1, 2] and target = 3, picking the first 1 with 2 and picking the second 1 with 2 both give [1, 2], but the result should contain it once.
Sorting the array places equal values next to each other. That lets the backtracking skip a value it has already tried at the same decision level, which is enough to prevent duplicate combinations from being generated at all.
1 <= candidates.length <= 100 → With n up to 100, we can't enumerate all 2^100 subsets. But the target is at most 30, and each candidate is at least 1, so any valid combination has at most 30 elements. This keeps the recursion tree shallow.1 <= candidates[i] <= 50 → All candidates are positive. This means the running sum only increases as we add elements, allowing us to prune when the sum exceeds the target.1 <= target <= 30 → The small target limits the number of valid combinations. Even though the array can have 100 elements, we'll never go deeper than 30 levels in the recursion.Ignore duplicates during generation and remove them afterward. Sort the array, generate every subset that sums to the target with standard include/exclude backtracking, and store each valid combination in a set so repeated combinations collapse into one entry.
Sorting matters even in this brute-force version. The recursion picks elements in index order, so on an unsorted array two index subsets with the same values can produce differently ordered lists ([7, 1] from one path, [1, 7] from another), and the set would treat them as distinct. Sorting first gives every combination a canonical order, so equal combinations compare equal.
The cost is wasted work: the search builds duplicate combinations in full, and the set immediately discards them.
The set exists only to discard combinations that were generated more than once. The next approach avoids generating them in the first place.
Sort the array and apply one rule during backtracking: at any given decision level, once a value has been tried, skip every later occurrence of that same value.
After sorting, duplicates sit next to each other. Each call loops over candidates from its start index to the right, so when i > start and candidates[i] == candidates[i-1], the value at index i was already tried at this level by the iteration at i-1, and the loop skips it.
Uniqueness: when candidates[i] == candidates[i-1] and i > start, every combination that begins by picking candidates[i] at this level was already produced when candidates[i-1] was picked, because the candidates available after index i are a subset of those available after index i-1. Skipping candidates[i] removes only repeats.
Completeness: the second copy of a value is still reachable as a deeper choice. With [1, 1, 6] and target = 8, the second 1 is skipped at the root level, but after picking the first 1 and recursing, the second 1 satisfies i == start at the next level and gets picked normally. [1, 1, 6] is still found, exactly once.
start to the end of the array. For each index i:candidates[i] exceeds the remaining target, break (all subsequent candidates are larger due to sorting).i > start and candidates[i] == candidates[i-1], skip this candidate (duplicate at the same level).candidates[i] to the current combination.i + 1 as the new start and remaining - candidates[i] as the new target.candidates[i] > remaining prune reduce the nodes visited in practice but do not improve the worst-case bound.target.A different way to handle duplicates works at the level of values instead of indices.
Count how many times each value appears, then backtrack over the unique values. For each unique value, decide how many copies to use (from 0 up to the available count), then move to the next unique value.
This reframes the problem from "which indices to pick" to "how many of each value to use," and no duplicate-skipping rule is needed because the search never sees the same value twice at one level. The deduplication argument is direct: two combinations produced by this search must differ in the copy count of at least one value, so they cannot be equal.
count copies, stopping the loop as soon as value * copies exceeds the remaining target.