Combination Sum | Medium | LeetCode#39. Combination Sum
🌐 中文版:繁體中文
Problem statement


- Difficulty:
Medium - Statement: given an integer array
candidatesand a target integertarget, return all unique combinations ofcandidateswhere the numbers in each combination sum totarget. You may return the combinations in any order.
In this problem, each number in candidates can be chosen an unlimited number of times. Two combinations are unique if at least one number is chosen a different number of times.
E.g. [2,2,3] != [2,2,2,2,3]
The test cases guarantee that the total number of unique combinations summing to the target is fewer than 150 for the given input.
Solution
Initial idea
Since it’s a combination problem, backtracking comes to mind immediately. Unlike 77. Combinations, this one doesn’t limit the depth, because the problem says numbers in candidates can be reused an unlimited number of times, so the termination condition isn’t limited by depth as usual.
We may need a variable to store the value at each choice, pass it to the next level to accumulate, and finally check whether it equals target. If not, keep choosing numbers. Also, unlike usual, since the same number can be reused, when entering each level we don’t skip the current number and can reselect it.
My solution
1 | class Solution { |
Here we again define a helper function to handle the main backtracking. Parameter explanation:
currentVal: the current combination’s running sumcandidate: the list of numbers giventarget: the target value givensubResults: the array holding the current combinationstart: controls the starting position of numbers
if(currentVal == target) is the recursion’s termination condition, meaning we found a valid sum. If the current sum currentVal is less than target, keep choosing numbers from candidate to combine. A for loop iterates candidate starting from index start, to ensure no duplicate combinations appear.
1 | combinationHelper(currentVal + candidate[i], candidate, target, subResults, i) |
After choosing a number candidate[i] each time, add it to the running sum currentVal and recurse to search the next number. Here i is passed to the recursive function, meaning the same number can be chosen multiple times.
I made a mistake before this: writing
currentVal += candidate[i]and passingcurrentVal. But this accumulates the change tocurrentValand can’t correctly restore its value after the recursion returns, affecting the whole search.
1 | subResults.pop_back() |
Backtrack to the previous choice.
Once target is found, the array is added to result, and finally we return the result.
Execution result

Complexity
Time complexity
At each recursion level, we can choose any candidate number, letting each number be chosen multiple times and forming a large number of combinations. Each choice to recurse produces two options: choose this number or not.
So considering all possible combinations, the time complexity can approach $O(2^n)$.
Space complexity
- Recursive call
In the worst case, the recursion depth depends on the target valuetarget. Each choice recurses, and as the sum keeps accumulating, the deepest recursion level can reach $O(target)$.
Each recursion stack level saves the current state (including parameters), so the worst-case stack space complexity is $O(target)$. - Result storage
resultstores all qualifying combinations. If the number of combinations found iskand each combination’s average length ism, the space for result storage is $O(k * m)$.
In the worst case, the number of combinations k can approach $O(2^n)$, since each candidate can be chosen multiple times. Each combination’s length m can also approachtargetin the worst case.
So the overall space complexity can be written as: $O(target+k⋅m)$



