diff --git a/39. Combination Sum.md b/39. Combination Sum.md new file mode 100644 index 0000000..8500917 --- /dev/null +++ b/39. Combination Sum.md @@ -0,0 +1,46 @@ +# [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>res; + void helper(vector& nums, const vector& 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> combinationSum(vector& candidates, int target) { + if(candidates.empty()) return res; + sort(candidates.begin(), candidates.end()); + vectornums; + helper(nums, candidates, 0, target); + return res; + } +}; +```