1.回溯算法回顾
题目1:组合77. 组合 - 力扣(LeetCode)
这道题是回溯的标准模板,参数和返回值、终止条件、for循环 参数处理 递归 回溯;然后就是有个剪枝的操作,还有就是 startindex是用来让组合不重复的
题目2:216. 组合总和 III - 力扣(LeetCode)
这个相较于第一题其实就是,把个数为k的组合进行一个求和判断然后再进行 reslut push_back即可。代码随想录里实在递归函数里加入了sum ,而我是每次path收集够k之后再进行sum计算。剪枝:每次sum > target就return 这已经算是剪枝了,但是剪枝不够彻底,因为约束了k个,所以也可以再for循环的条件是进行剪枝, i < = n - (k - path.size() ) + 1
class Solution {
public:
vector<int> list;
vector<vector<int>> reslut;
void backtarcking(int k, int n, int startindex, int sum) {
if(list.size() == k) {
if(sum == n) reslut.push_back(list);
return;
}
for(int i = startindex;i <= 9 - (k - list.size()) + 1 && sum + i <= n;i++) {
sum += i;
list.push_back(i);
backtarcking(k, n, i + 1, sum);
sum -= i;
list.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtarcking(k, n, 1, 0);
return reslut;
}
};
题目3:17. 电话号码的字母组合 - 力扣(LeetCode)
这道题需要构建一个字符串数组,然后对输入的数组字符串进行递归即可,这里for循环每次都是从 I = 0开始,然后 i < st[id].size() ,终止条件就是每次字符串tmp的个数和输入的数字字符串相等就return
这个题和组合III的区别就是 回调函数 startindex = i 而不是 i+1 因为该题允许同一个数字被重复使用,这里剪枝如果再for循环里加入 sum+ can[i] 约束是需要对数组进行排序的,不排序可以这样
class Solution {
public:
vector<vector<int>> reslut;
vector<int> path;
void backtracking(const vector<int>& candidates, int sum, int target, int startindex) {
// if(sum > target) return;
if(sum == target) {
reslut.push_back(path);
return;
}
for(int i = startindex;i < candidates.size();i++) {
if(sum + candidates[i] > target) continue;
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, sum, target, i);
sum -= candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates, 0, target, 0);
return reslut;
}
};
题目5:40. 组合总和 II - 力扣(LeetCode)
这个去重是要对树层里的相同元素剪枝,树枝里不进行剪枝,剪枝可以通过比下标进行也可以定义一个数组 这里是 如果used[i - 1] = true证明是树枝,这时候可以选取相同的元素,如果used[i - 1]=false 证明是树层,这时候就要 continue剪枝了
题目 6:131. 分割回文串 - 力扣(LeetCode)
分割回文串其实类似于组合,用startindex来代表切割的地方,然后就是判断是否是回文字符串就用双指针就好
题目7:93. 复原 IP 地址 - 力扣(LeetCode)
这里终止条件通过IP中的 加入的点个数判断,== 3时 return,这时候后面的字符串还没有处理,所以需要在终止判断里进行处理,然后就是判断字符串可行性的时候在for循环里 判断是否有非法字符同时在里面判断是否>255 ,否则加完所有算容易溢出,还要保证 起始不能大于end 否则会出现最后一个字符串段没有字符
自己问题没有终止条件判断,然后每个节点都要加入到reslut里,这里startinedx = i + 1
这里就是树层去重可用下标也可以用 used数组,还可以用set去重
题目10:491. 非递减子序列 - 力扣(LeetCode)
这个因为没办法进行数组排序,所有必须借助unordered_set set集合进行树层的去重
题目11、12:46. 全排列 - 力扣(LeetCode)47. 全排列 II - 力扣(LeetCode)
全排列,通过一个uesd数组进行数据选择,for循环的时候i=0开始,
排序之后可以通过i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false进行树层去重
2.新题目:332. 重新安排行程 - 力扣(LeetCode)
3.新题目:51. N 皇后 - 力扣(LeetCode)
4.新题目:37. 解数独 - 力扣(LeetCode)