LeetCodeHot100_39——《组合总和》
解题思路:这道题回溯算法的典型例题之一了属于,回溯算法的解题步骤,可以用树结构画出来便于理解。用例二举例来看(图太长了,不画完了,思路大概就是这样):
回溯法的使用,从代码随想录中学到了大概的步骤流程:
①确定递归函数参数:
vector<vector<int>> result; //建立一个二维数组,存最后的答案
vector<int> path;//建立一个数组,用来临时存放答案
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
}
②确定递归的终止条件:
这道题从树结构中就能看出来,只有当sum这个和大于等于target才会停止递归,如果等于target还需要返回答案数组。
if (sum > target)
{
return;
}
if (sum == target)
{
result.push_back(path);//如果sum == target把临时答案数组压入最后输出答案数组result
return;
}
③确定单层搜索的逻辑:
for (int i = startIndex; i < candidates.size(); i++) //这里注意的是树结构的每一层就可以看成是for循环遍历一次candidates
{
sum += candidates[i]; //求和
path.push_back(candidates[i]); //讲用于求和的数放进临时答案数组中
backtracking(candidates, target, sum, i); //进行递归调用,因为是可以重复运算自身的,所以这个这里传入i,意思是下次的递归调用也是从这次的数字开始算
sum -= candidates[i];//调用之后需要回溯,回溯则需要和sum和path都减掉上一次增加的值
path.pop_back();
}
最后代码:(回溯算法感觉就是需要多练习并且多调试,多理解,才会做)
#include<iostream>
#include<vector>
using namespace std;
vector<vector<int>> result; //建立一个二维数组,存最后的答案
vector<int> path;//建立一个数组,用来临时存放答案
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
if (sum > target)
{
return;
}
if (sum == target)
{
result.push_back(path);
return;
}
for (int i = startIndex; i < candidates.size(); i++)
{
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, target, sum, i);
sum -= candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
result.clear();
path.clear();
backtracking(candidates, target, 0, 0);
return result;
}
int main() {
vector<int> candidates = { 2,3,5 };
int target = 8;
vector<vector<int>> test = combinationSum(candidates, target);
return 0;
}