周末两天补了补项目,玩了玩,没做题呜呜呜
回溯算法
回溯与递归相辅相成,用于解决:组合、分割、子集、排列、棋盘问题
46.全排列
模板:
void backtrack(参数) {
if (终止条件) {
记录结果;
return;
}
for (选择 : 所有可选项) {
if (剪枝条件) continue;
做出选择(path.push_back, used[i]=true);
backtrack(下一层参数); // 递归
撤销选择(path.pop_back, used[i]=false); // 回溯
}
}
到最后一层之后要pop_back、used置为false,表示当前分支探索完,回溯上去尝试其他分支
算了还是按照代码随想录顺序系统看一下吧
第77题. 组合
组合问题不能重复取,需要一个startindex来控制
照着回溯模板:
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
class Solution {
private:
vector<vector<int>> result; // 存放符合条件结果的集合
vector<int> path; // 用来存放符合条件结果
void backtracking(int n, int k, int startIndex) {
if (path.size() == k) {
result.push_back(path);
return;
}
for (int i = startIndex; i <= n; i++) {
path.push_back(i); // 处理节点
backtracking(n, k, i + 1); // 递归
path.pop_back(); // 回溯,撤销处理的节点
}
}
public:
vector<vector<int>> combine(int n, int k) {
backtracking(n, k, 1);
return result;
}
};
216.组合总和III
比上一题终止条件多了一个判断总和是否等于目标和,循环的时候累加一个sum
17.电话号码的字母组合
数字和字母之间要用map做映射,或者用一个二维数组:
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
这题就不需要startindex了,因为是在不同的集合中取数
还需要将字符串表示的数字转换成int类型的
int digit = digits[index] - '0'; //'2'转换为数字2...
string letters = letterMap[digit]; //2转换为abc
for (int i = 0; i < letters.size(); i++) { // 从abc中取a、b、c
s.push_back(letters[i]);
backtracking(digits, index + 1);
s.pop_back();
}
39. 组合总和
可以重复取数
backtracking(candidates, target, sum, i); // 关键点:不用i+1了,表示可以重复读取当前的数
40.组合总和II
这题就不能重复取数了,但是数组中可能会有重复元素,上一题是无重复元素数组
像全排列那样,用一个used数组来去重
初始化used数组
vector<bool> used(candidates.size(), false);
排序
// 首先把给candidates排序,让其相同的元素都挨在一起。
sort(candidates.begin(), candidates.end());
去重:
used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
used[i - 1] == false,说明同一树层candidates[i - 1]使用过
// 要对同一树层使用过的元素进行跳过
if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {
continue;
}
131.分割回文串
substr用法
// 获取[startIndex,i]在s中的子串
string str = s.substr(startIndex, i - startIndex + 1);
path.push_back(str);
写到这去面了一家机器人公司,真的是被拷打麻了,唉基础知识还是掌握的不够
93.复原IP地址
要添加逗点、根据逗点的数量是否为3且第四段子串合法作为终止条件
78.子集
做组合时候的所有节点都是子集
90.子集II
数组中有重复元素,要做数层去重
所以依然是先排列,判断前后是不是相等、有没有用过
勉勉强强做出来了
先做到这吧!!