# LC 39. Combination Sum
### [Problem link](https://leetcode.com/problems/combination-sum/)
###### tags: `leedcode` `medium` `c++` `Backtracking`
Given an array of **distinct** integers <code>candidates</code> and a target integer <code>target</code>, return a list of all **unique combinations** of <code>candidates</code> where the chosen numbers sum to <code>target</code>. You may return the combinations in **any order** .
The **same** number may be chosen from <code>candidates</code> an **unlimited number of times** . Two combinations are unique if the **frequency** of at least one of the chosen numbers is different.
The test cases are generated such that the number of unique combinations that sum up to <code>target</code> is less than <code>150</code> combinations for the given input.
**Example 1:**
```
Input: candidates = [2,3,6,7], target = 7
Output: [[2,2,3],[7]]
Explanation:
2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times.
7 is a candidate, and 7 = 7.
These are the only two combinations.
```
**Example 2:**
```
Input: candidates = [2,3,5], target = 8
Output: [[2,2,2,2],[2,3,3],[3,5]]
```
**Example 3:**
```
Input: candidates = [2], target = 1
Output: []
```
**Constraints:**
- <code>1 <= candidates.length <= 30</code>
- <code>2 <= candidates[i] <= 40</code>
- All elements of <code>candidates</code> are **distinct** .
- <code>1 <= target <= 40</code>
## Solution 1
#### C++
```cpp=
class Solution {
public:
vector<vector<int>> res;
void backtracking(vector<int> &candidates, int target, vector<int> &path, int &pathSum, int startIdx) {
if (pathSum >= target) {
if (pathSum == target) {
res.push_back(path);
}
return;
}
for (int i = startIdx; i < candidates.size(); i++) {
path.push_back(candidates[i]);
pathSum += candidates[i];
backtracking(candidates, target, path, pathSum, i);
path.pop_back();
pathSum -= candidates[i];
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<int> path;
int pathSum = 0;
backtracking(candidates, target, path, pathSum, 0);
return res;
}
};
```
剪枝後
```cpp=
class Solution {
public:
vector<vector<int>> res;
void backtracking(vector<int> &candidates, int target, vector<int> &path, int &pathSum, int startIdx) {
if (pathSum >= target) {
if (pathSum == target) {
res.push_back(path);
}
return;
}
for (int i = startIdx; i < candidates.size() && pathSum + candidates[i] <= target; i++) {
path.push_back(candidates[i]);
pathSum += candidates[i];
backtracking(candidates, target, path, pathSum, i);
path.pop_back();
pathSum -= candidates[i];
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<int> path;
int pathSum = 0;
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, path, pathSum, 0);
return res;
}
};
```
>### Complexity
>n = candidates.length
>| | Time Complexity | Space Complexity |
>| ----------- | --------------- | ---------------- |
>| Solution 1 | O(n * 2^n) | O(n * 2^n) |
## Note
剪枝多了
```cpp=
sort(candidates.begin(), candidates.end());
及
for (int i = startIdx; i < candidates.size() && pathSum + candidates[i] <= target; i++)
```
因為如果目前的合大於target就沒必要進入下層循環了, 如果要這樣判斷就要先用sort排序