没啥说的……写完以后感觉自己以后都可以写backtrack的题惹!
昨天看论坛上有一句话对于backtrack写的很好:你需要把算法穷举的结果想象成一棵树,然后对其进行剪枝,大概是这样子吧……
主要一开始卡壳的原因是不知道如果return返回到上一层的话,上一层怎么返回到上上层,其实要把上一层的值pop出来就好了……就是说,尝试过第n层递归中的各种情形之后,发现此路不通,那么第n-1个push进来的值实际上也是没用的,因为走不下去,所以需要把它pop出去然后进行下一次尝试。
39的代码
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<int> sol;
dfs(candidates,sol,target,0,0);
return res;
}
void dfs(vector<int>& can,vector<int> sol,int target, int index,int sum){
if(index>can.size()) return;
for(int i=index;i<can.size()&&can[i]<=target;i++){
if((sum+can[i])==target) {sol.push_back(can[i]); res.push_back(sol); return;}
else if((sum+can[i])<target){
sol.push_back(can[i]);
dfs(can,sol,target,i,sum+can[i]);
}
else return;
sol.pop_back();
}
}
};
二刷
不知道为什么采用-target的办法比+sum的办法要快很多。
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<int> sub;
dfs(candidates, sub, target, 0);
return res;
}
void dfs(vector<int>& candidates, vector<int>& sub, int target, int index){
if(!target){
res.push_back(sub);
return ;
}
for(int i=index; i!=candidates.size()&&candidates[i]<=target; ++i){
sub.push_back(candidates[i]);
dfs(candidates, sub, target-candidates[i], i);
sub.pop_back();
}
}
};
40也就是在30的基础上注意一下递归调用dfs的时候传的index为i+1而不是i
同时最后避免一下duplicates
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
vector<int> sol;
dfs(candidates,sol,target,0,0);
return res;
}
void dfs(vector<int> can,vector<int> sol,int target,int sum,int index){
if(index>=can.size()) return;
for(int i=index;i<can.size();i++){
if(sum+can[i]<target){
sol.push_back(can[i]);
dfs(can,sol,target,sum+can[i],i+1);
}
else if(sum+can[i]==target){
sol.push_back(can[i]);
res.push_back(sol);
return;
}
else return;
sol.pop_back();
while(can[i]==can[i+1]) i++;
}
}
};
二刷:
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<int> sub;
dfs(candidates, sub, target, 0);
return res;
}
void dfs(vector<int>& candidates, vector<int> sub, int target, int index){
if(!target){
res.push_back(sub);
return ;
}
for(int i=index; i!=candidates.size()&&candidates[i]<=target; ++i){
sub.push_back(candidates[i]);
dfs(candidates, sub, target-candidates[i], i+1);
sub.pop_back();
while(candidates[i]==candidates[i+1]) i++;
}
}
};
77的代码
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combine(int n, int k) {
vector<int> sol;
backtrack(sol,n,k,1);
return res;
}
void backtrack(vector<int>& sol,int n,int k,int index){
int s=sol.size();
if(s==k) {res.push_back(sol);return;}
for(int i=index;i<=n;i++){
sol.push_back(i);
backtrack(sol,n,k,i+1);
sol.pop_back();
}
}
};
其实不太明白为什么这么慢…………难道用动态规划会快一点么……