回溯算法
回溯算法,干就完事了
baixiaofei567
如果十年前没种树,那最好的时间是现在
展开
-
1723. 完成所有工作的最短时间
一眼就感觉是dfs爆搜,肯定超时,正解应该是递归回溯+二分+剪枝(做不来hhh)超时版本:class Solution {public: //第一个参数是当前处理到的工作数量,第二个参数是当前所有人中的最大工作时间 void dfs(int u,int maxn,vector<int>& jobs,int k){ //剪枝 if(maxn >= res) return;//当前已经不可能成为最优解了 //递归边.原创 2021-05-08 23:28:00 · 251 阅读 · 0 评论 -
51. N 皇后
和数独差不多,要注意的是,有些操作能省则省,可以省下不少时间。自己定义一个二维数组存n*n的棋盘会很方便。检测当前能否填皇后的函数是要检查同一行同一列,以及左上45度以及右上45度,因为我们是从上往下填的,所以只需要判断上方的就行了。如果到了递归边界,就通过该bord生成一个vector然后加入res,这样不用自己手动维护vector< string >了很方便。dfs中就是遍历当前行的每一列看看能否填上Q,如果可以就填上,然后直接去下一行,这就是我说的省下来的操作,不用去下一列了,当..原创 2021-02-25 15:27:42 · 87 阅读 · 0 评论 -
37. 解数独
这种细节满满的hard题还是很累人的,主要是穷举+dfs+剪枝,有一个地方让我卡了挺久的,在当前层遍历的时候,如果碰到了已经填好的数字,应该是dfs当前行下一列!!然后再continue。递归边界就是到了越界的那一行n就证明找到解了,不然到不了这里,如果当列到了9,就去下一行。最难的就是九宫格判断是否有重复的,一定要多思考思考class Solution {public: bool isValid(int r,int c,char n,vector<vector<char>.原创 2021-02-25 15:21:01 · 109 阅读 · 0 评论 -
131. 分割回文串
dfs加回文串的easy题。如果当前的子串是回文串,就有两种情况,在这里切一刀,往后继续找,或者带着自身这个回文串继续往后找。递归边界就是index走到字符串的最后一位,而且加上最后一位的tmp是回文串,就让tmp数组加入这个回文串,然后res加入tmp数组class Solution {public: bool isPalind(string s){ string tmp = s; reverse(tmp.begin(),tmp.end()); .原创 2021-02-08 01:31:50 · 119 阅读 · 0 评论 -
216. 组合总和 III
比I和II都简单class Solution {public: void dfs(int index, int k, int n){ if(tmp.size() == k){ if(n == 0){ res.push_back(tmp); } return; } for(int i = index+1; i <= 9; ++i){ .原创 2021-02-24 01:08:25 · 62 阅读 · 0 评论 -
40. 组合总和 II
和去重有关的回溯就可以算得上好题这里的去重比前几个难一点,不要用set效率太低了。还是先排序,我们要的是在当前层不能取相同的数字,而在下一层还是可以取的,所以和排列的简单的和前面比较不同。要在i>index的情况下和前面比,如果i==index,那么不管前面是什么,当前层是第一次取这个数字是没关系的。i>index这个条件很重要class Solution {public: void dfs(vector<int>& candidates, int targ.原创 2021-02-24 01:07:27 · 70 阅读 · 0 评论 -
77. 组合
组合就很简单,不用去重,也不用考虑重复数字class Solution {public: void dfs(int index, int n, int k){ if(tmp.size() == k){ res.push_back(tmp); } for(int i = index; i <= n; ++i){ //传参不要传错了!传的是i+1不是index+1 tmp..原创 2021-02-24 01:03:21 · 74 阅读 · 0 评论 -
257. 二叉树的所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。说明: 叶子节点是指没有子节点的节点。示例:输入: 1 / \2 3 \ 5输出: ["1->2->5", "1->3"]解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode原创 2020-08-25 23:43:37 · 93 阅读 · 0 评论 -
93. 复原IP地址
十道回溯剪枝就这一道难的,感觉重回pat那时候的字符串大模拟,不过确实是好题。用一个vector来存每个字段的数字即可,这样可以在最后在进行IP地质的拼接。这道题最重要的就是剪枝。递归边界就是tmp.size()==4了,如果s用完了,就将tmp数组里的字符串拼接成IP地址即可。然后不管是否用完s,都要return了。从当前位开始最多往后取3位,从1遍历到3。此时第一个剪枝操作:如果当前起始字符+要截取的字符长度越界了,直接return。第二个剪枝操作:截取的这一字段的字符串对应的数字大于255也r.原创 2021-02-24 00:44:38 · 116 阅读 · 0 评论 -
79. 单词搜索
二维数组无脑dfs。记得将vis[i][j]在用完后设为falseclass Solution {public: bool dfs(int i, int j, int index, vector<vector<char>>& board,string word,vector<vector<bool>>& vis){ if(index > word.length()-1) return true; .原创 2021-01-26 01:55:55 · 67 阅读 · 0 评论 -
78. 子集
集合一般就是回溯。class Solution {public: void dfs(int index,vector<int>& nums,vector<int>&tmp){ res.push_back(tmp); //不用递归边界,因为不会越界,是通过for循环来的,不会无限递归 for(int i = index; i < nums.size(); ++i){ tmp.pu.原创 2021-01-26 01:54:33 · 86 阅读 · 0 评论 -
46. 全排列
经典回溯,看成一棵树,就是选择和不选择的过程,如果已经有这个数了,就不能选择这个数了,走到叶子结点后会自动回溯,记得在回上一层时pop_back当前层的数字。class Solution {public: void dfs(vector<int>&nums){ if(tmp.size() == nums.size()){ res.push_back(tmp); return; } .原创 2021-01-22 02:06:30 · 71 阅读 · 0 评论 -
39. 组合总和
经典的回溯,我发现我的不足在于老是不知道什么时候回溯,就是什么时候弹出class Solution {public: //回溯需要知道自己当前遍历到数组中的哪个书,并且递归要有两个关键的 void dfs(vector<int>& candidates, vector<int>& tmp, int target, int index){ //递归边界,等于target了就返回,或者target已经取不到0了 //上.原创 2021-01-21 01:57:36 · 113 阅读 · 0 评论 -
17. 电话号码的字母组合
一看就是dfs,其实算是比较简单的dfs了,我居然还做不出,我真是个sb。来一个index记录当前遍历到给定字符串的哪一位即可。在dfs里,如果遍历到最后一位了,就将临时字符串加入结果数组。如果没有,就遍历当前字符串中的数字对应的所有的字母,用一个vector来存即可,循环中将tmp+上当前数字的对应字母,然后对其dfs,并将index+1,遍历完后回溯,就是将tmp最后一个字符删掉,用erase(tmp.end()-1)即可,因为end()迭代器是最后一位的后一位,不指向任何字符。class Solu.原创 2021-01-16 02:59:05 · 167 阅读 · 0 评论 -
剑指offer——矩阵中的路径C++
dfs+回溯。此处回溯的思想大概就是自动回溯?1.char*和string可以直接比较。2.bool数组必须手动fill,不然不是全为false的。3.传输组,形参要写数组,实参写数组名,因为相当于传一个指针,所以回改变实参的值。class Solution {public: //此字符串不是二级指针,不会改变原来的值,所以不用erase尾部 //传的是一个数组,其实相当于传进去一个指向数组首部地址的指针,会改变原数组的值 bool dfs(char* matrix, ..原创 2021-01-07 01:53:23 · 195 阅读 · 0 评论 -
剑指offer——字符串的排列C++
必须花点时间搞清楚回溯算法了,忘得一干二净最好的题解,摘自牛客大佬import java.util.ArrayList;import java.util.List;import java.util.Collections;public class Solution { public ArrayList<String> Permutation(String str) { List<String> resultList = new ArrayList&.原创 2020-12-27 02:11:46 · 171 阅读 · 0 评论 -
1103 Integer Factorization (30分)
The K−P factorization of a positive integer N is to write N as the sum of the P-th power of K positive integers. You are supposed to write a program to find the K−P factorization of N for any positive integers N, K and P.Input Specification:Each input fi原创 2020-11-06 01:09:49 · 109 阅读 · 0 评论 -
47. 全排列 II
给定一个可包含重复数字的序列,返回所有不重复的全排列。示例:输入: [1,1,2]输出:[[1,1,2],[1,2,1],[2,1,1]]class Solution {public: vector<vector<int>> res; vector<vector<int>> permuteUnique(vector<int>& nums) { vector<int> track原创 2020-08-16 00:18:36 · 81 阅读 · 0 评论 -
46. 全排列
给定一个 没有重复 数字的序列,返回其所有可能的全排列。示例:输入: [1,2,3]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]class Solution {public: vector<vector<int>> res; vector<vector<int>> permute(vector<int>& nums) { v原创 2020-08-16 00:13:02 · 77 阅读 · 0 评论 -
90. 子集 II
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。说明:解集不能包含重复的子集。示例:输入: [1,2,2]输出:[[2],[1],[1,2,2],[2,2],[1,2],[]]class Solution {public: vector<vector<int>> res; vector<vector<int>> subsetsWithDup(vector<int>&原创 2020-08-15 00:07:13 · 91 阅读 · 0 评论 -
回溯算法
照搬labuladong,有需要直接百度这位大佬即可废话不多说,直接上回溯算法框架。解决一个回溯问题,实际上就是一个决策树的遍历过程。你只需要思考 3 个问题:1、路径:也就是已经做出的选择。2、选择列表:也就是你当前可以做的选择。3、结束条件:也就是到达决策树底层,无法再做选择的条件。如果你不理解这三个词语的解释,没关系,我们后面会用「全排列」和「N 皇后问题」这两个经典的回溯算法问题来帮你理解这些词语是什么意思,现在你先留着印象。代码方面,回溯算法的框架:result = []def b原创 2020-08-14 23:52:59 · 140 阅读 · 0 评论 -
78. 子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。说明:解集不能包含重复的子集。示例:输入: nums = [1,2,3]输出:[[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[]]class Solution {public: vector<vector<int>> res; vector<vector<int>> subsets(vector<in原创 2020-08-14 23:45:05 · 148 阅读 · 0 评论