---
# System prepended metadata

title: LC 39. Combination Sum
tags: [medium, leedcode, Backtracking, c++]

---

# 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排序
