77. 组合(题目链接:力扣)
思路:今天开始进军回溯法了,回溯法用来做暴力题还是很得劲儿的。这道典型的排列组合题,直接递归遍历,顺便在进入递归前进行一下剪枝操作。
vector<vector<int>> result;
void backStriping(vector<int>& tmp, int start, int end, int k){
if(k==0){
result.push_back(tmp);
return;
}
for(int i=start; i <= end-k+1; i++){
tmp.push_back(i);
backStriping(tmp, i+1, end, k-1);
tmp.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
vector<int> tmp;
backStriping(tmp, 1, n, k);
return result;
}
216. 组合总和 III(题目链接:力扣)
思路:和上题没有太大差别,也是从给定数中挑选组合,就是需要额外参数记录之前所选数的和,另外剪枝可以写的更丰富,遍历到某个数,判断当前所选数的和是否明显太小或者太大,而不是一直算完发现太大了或者太小了才返回。另外一个剪枝操作就是普遍要写的——当剩余的数的数量恰好够满足条件k时,就不要再让其一个一个挑了,直接一遍遍历即可。
vector<vector<int>> result;
void backtracking(vector<int>& tmp, int start, int k, int tmpNum, int target){
if(k==0){
if(tmpNum == target) result.push_back(tmp);
return;
}
for(int i=start; i<=9-k+1 && tmpNum+9*k>=target && tmpNum+start*k<=target; i++){
tmp.push_back(i);
tmpNum += i;
backtracking(tmp, i+1, k-1, tmpNum, target);
tmpNum -= i;
tmp.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
vector<int> tmp;
backtracking(tmp, 1, k, 0, n);
return result;
}
不知不觉二叉树就这么过了,总有点意犹未尽的感觉,感觉自己肯定还没有牢牢掌握所有重点,浅浅复习一下子。