# [39. Combination Sum](https://leetcode.com/problems/combination-sum/)
# 思路
题意：从一个无重复元素的数组里面选一些数字出来，使这些数字的和恰好为target，数组里的数字可以重复使用。     
就是一个回溯题（类似DFS），另外为了避免得到重复结果，先对数组进行排序（常规操作）。    
为了进行递归调用，我们定义了一个函数helper，传入的参数有
* nums - 当前被选中的数
* candidates - 就是题意里面的数组（从小到大排序好的）
* start - 只能考虑数组candidates下标为start及后面的数
* curr_target - 当前的目标（我们希望的就是nums的元素和加上curr_target就等于target）

helper函数定义如下：
* 当`curr_target == 0`时，说明nums的元素和就等于target，nums就是一组我们要求的数，push进结果数组即可。
* 当`start >= candidates.size()`时，说明start已经超过了candidates最大下标，返回即可；
* 当`candidates[start] > curr_target`时，说明candidates中（当前可用的）最小的数都比curr_target大，也是直接返回。
* 前面三个条件都不满足时，就有两条路要走: 
  1. 将candidates[start]加入到nums中，令`curr_target = curr_target - candidates[start]`, 进入下一层递归；
  2. 不将candidates[start]加入到nums中, 令`start + 1`,进入下一层递归；

# C++
``` C++
class Solution {
private:
    vector<vector<int>>res;
    void helper(vector<int>& nums, const vector<int>& candidates, const int& start, const int& curr_target){
        if(curr_target == 0){
            res.push_back(nums);
            return;
        }
        if(start >= candidates.size() || candidates[start] > curr_target) return;

        nums.push_back(candidates[start]);
        helper(nums, candidates, start, curr_target - candidates[start]);
        nums.pop_back();
        helper(nums, candidates, start + 1 , curr_target);
        return;
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        if(candidates.empty()) return res;
        sort(candidates.begin(), candidates.end());
        vector<int>nums;
        helper(nums, candidates, 0, target);
        return res;
    }
};
```
