题目:
思路:
1. 这是一道搜索和回溯的题目,首先要画出树形图,根据树的推理逻辑写代码;
2. 题目要求返回每个组合中元素的具体数值。需要在搜索过程中记录中间数值,采用深度优先搜索比较合适。
3. 题目要求组合不能重复,例如,[2,3,3],[3,2,3],[3,3,2]视为同一个组合。这里有一个trick可以在搜索过程中排除重复的组合:首先将候选数组排序,每次减去的数值都不能小于前一次减去的数值。这一步trick体现在函数searchDFS的参数start中。
class Solution {
public:
vector<int> candidate;
void searchDFS(int start, int target, vector<int>& path, vector<vector<int> >& res) {
if(target == 0) {
res.push_back(path);
return;
}
if(target < candidate[start]) // 非常重要的判断条件
return;
for(int i = start; i < candidate.size(); ++i) {
path.push_back(candidate[i]);
searchDFS(i, target-candidate[i], path, res);
path.pop_back(); // 非常巧妙的回溯操作
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<int> caseVec;
vector<vector<int> > result;
sort(candidates.begin(), candidates.end());
this->candidate = candidates;
searchDFS(0, target, caseVec, result); // 深度优先搜索,每找到一条完整路径就保存
return result;
}
};
执行用时 :8 ms, 在所有 cpp 提交中击败了99.81%的用户
内存消耗 :9.3 MB, 在所有 cpp 提交中击败了93.54%的用户