![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
回溯
algsup
这个作者很懒,什么都没留下…
展开
-
leetcode刷题总结之回溯法
前言:好久没写总结了,总感觉心里空空的。回溯法是看labuladong的详解回溯法入的门,然后看了《计算机算法设计与分析》第5章的回溯法部分弄清了原理,今日总结一下,供以后复习用。回溯法的定义:回溯法有通用解法的美称,对于很多问题,如迷宫等都有很好的效果。回溯法实际就是对问题的解空间树采用深度优先搜索的方式,搜索需要解决问题的任一解或者所有解,它是一个既带系统性又带跳跃性的搜索算法。回...原创 2019-11-27 22:02:44 · 3416 阅读 · 0 评论 -
[回溯]leetcode1219:黄金矿工(medium)
题目:题解:思路:回溯法,枚举每个不为0的点作为起点,向四周扩展,每次更新最长路径长度即可。代码如下:class Solution {public: int getMaximumGold(vector<vector<int>>& g) { int m=g.size(),n=g[0].size(); int dx[]={1,-1,0,0},dy[]={0,0,1,-1}; int res=0;原创 2022-02-05 13:24:55 · 824 阅读 · 0 评论 -
[回溯]leetcode1718:构建字典序最大的可行序列(medium)
题目:看数据范围 n 最大取20,所以直接一个回溯就行了,注意这是一个带bool型的回溯,与平时写的void型的不一样,所以我们直接将 n 从大到小进行枚举,这样找到最优解之后,一路返回 ture,得到正确答案就行了。这里提供两种版本的代码,思路都是一样的,学习下码风就行。代码如下:bool visited[45];class Solution {public: vector<int> res,trace; vector<int> constr原创 2021-02-20 21:43:15 · 264 阅读 · 1 评论 -
[回溯]leetcode491:递增子序列(medium)
题目:题解:回溯法一般套路,生成组合问题,这里注重讲一下index吧。由于是生成组合并不是生成排序,所以进行下一次决策的话,我们需要将i+1,表示i表示的数字已经加入决策路径了,只有回溯回来的时候i+1会还原成i,然后++i,我们重新生成下一个组合。代码如下:class Solution {public: vector<vector<int>>...原创 2020-01-29 00:17:13 · 343 阅读 · 0 评论 -
[回溯]leetcode5123:字母组合迭代器(medium)
题目:题解:回溯法回溯法标准框架,注意这里的index是用来遍历str的代码如下:class CombinationIterator {private: deque<string> paths;public: //题解:回溯法 CombinationIterator(string& characters, int combinat...原创 2019-12-15 08:30:52 · 185 阅读 · 0 评论 -
[回溯法][树]leetcode113:路径总和 Ⅱ (medium)
对于树形结构采用dfs的策略寻找所有可行解,就是运用的回溯法。原创 2019-12-06 20:59:31 · 253 阅读 · 1 评论 -
[回溯法]leetcode216:组合总和 Ⅲ (medium)
题目:题解:回溯法回溯法的框架题,注意判断找到一个可行解的标志是索引index与决策路径的大小相等,且决策路径的总和与n相等;若大于等于决策路径大小或sum大于n,表示我们走弯路了,需要返回上一层。还有需要注意组合中的数只能为1-9的数字,且不能重复,所以我们按顺序增长就好了,这样就不会重复了。代码如下:class Solution {public: //题解:回溯法...原创 2019-12-06 19:33:17 · 159 阅读 · 0 评论 -
[回溯+剪枝]leetcode140:单词拆分 Ⅱ(hard)
题目:140. 单词拆分 II题解:回溯+剪枝若使用回溯法一般框架,对于aaa...aaa这种字符串时,会造成大量重复计算从而导致超时现象,所以我们需要加个map存放<s,result>,这样达到剪枝的效果,优化时间。代码如下:class Solution {public: vector<string> wordBreak(string s...原创 2019-12-06 17:21:46 · 274 阅读 · 0 评论 -
[回溯]leetcode10:正则表达式匹配(hard)
题目:10.正则表达式匹配题解:题解①:利用C++的正则表达式库进行匹配(作弊行为)题解②:回溯法1)如果不考虑*,那么我们直接遍历两个字符串比较每个字符是否匹配即可。然而我们模式串p中是含有*的,那么我们应该如何处理*呢?2)对于模式串中的*,它一般出现在p的第二个位置,比如:a*、c*a*b,即p[1]。对于这种情况,我们可以直接忽略模式串中的前两个字符,比如:aab...原创 2019-11-04 17:02:24 · 321 阅读 · 0 评论 -
[回溯]leetcode17:电话号码的字母组合(medium)
题目:题解:回溯法对于字符数字对应的字符串之间的映射,在这里我们不使用map,而是直接使用array的下标数字对应字符串,建立好映射后,接下来就是回溯法的一般方法了。代码如下:class Solution {public: vector<string> letterCombinations(string digits) { if(digit...原创 2019-11-04 23:14:22 · 355 阅读 · 0 评论 -
[回溯]leetcode22:括号生成(medium)
题目:题解:回溯法本题使用n来表示左括号可以使用个数,用index来表示右括号可以使用的次数。在每使用掉一个左括号时,对应可以使用右括号的数量+1,因为这样可以保证左右括号是对等的(也就是先有左括号,然后再有右括号,这样就避免无效括号了)。当可以使用可以左右括号个数为0时,表示已经生成一个有效的括号组合。代码如下:class Solution {public: v...原创 2019-11-05 16:50:06 · 166 阅读 · 0 评论 -
[回溯]leetcode37:解数独(hard)
题目:37.解数独题解:回溯法1)建立三个二维数组分别用来表示:每行的10个数字(0~9)row[9][10],用9行;每列的10个数字col[9][10],共9列;每个小方块的10个数字box[9][10],共9个小方块。用solved来表示在每行每列每个小方块中是否出现了重复数字,是则为false,不是则为true。2)在j<8时开始遍历第i+1行的每一个数字,检查行、...原创 2019-11-07 15:40:56 · 330 阅读 · 0 评论 -
[回溯]leetcode39:组合总和(medium)
题目:题解:回溯法的2部曲:1)找到一个解:将此决策路径添加到result中2)没找到解,开始枚举所有决策路径:2.1)choose过程:将某个选择添加到决策路径2.2)进入下一步决策:这时的决策路径已变大,选择列表也变化了2.3)unchoose过程:将上面那个选择移除决策路径,然后此选择重新返还到选择列表代码如下:class Solution...原创 2019-11-07 16:25:54 · 237 阅读 · 0 评论 -
[剪枝+回溯]leetcode40:组合总数 Ⅱ (medium)
题目:题解:本题与39.组合总和的区别:在于candidates 中的数字可以是否可以重复多次。因此在递归的时候index为i+1,而不是上一题的index为i。关于剪枝问题:由于连续重复数字在生成一个组合数组的时候,会出现重复组合数组,所以再次遇到连续重复数字的时候我们直接跳过即可。代码如下:class Solution {public: vector<vector...原创 2019-11-07 17:05:59 · 229 阅读 · 0 评论 -
[回溯][dp]leetcode44:通配符匹配(hard)
题目:44.通配符匹配题解:解法1:回溯法last:用来记录最后一次匹配的位置;star:用来记录*的位置开始进行匹配,若i小于s串的长度,进行for循环。若当前两个字符相等,或着p中的字符是问号(?),则i和j分别加1。若 p[j] 是星号,要记录星号的位置,star赋为j,此时j再自增1,last赋为i。若当前 p[j] 不是星号,并且不能跟 p[i] 匹配上,此时就要靠*了...原创 2019-11-10 23:50:17 · 353 阅读 · 0 评论 -
[回溯]leetcode46:全排列(medium)
题目:46.全排列题解:注:本题思路来自:labuladong的回溯算法详解对于回溯算法,需要知道可以进行的选择列表choiceList以及决策路径track(即已经做出一系列选择)。对于如何让计算机正确地穷举并比较所有决策,就需要回溯算法的设计技巧了,回溯算法的核心就在于如何设计 choose 和 unchoose 部分的逻辑。全排列中的选择列表:每次选择的一个数 决策路径...原创 2019-11-01 17:16:13 · 367 阅读 · 0 评论 -
[回溯+剪枝]leetcode47:全排列 Ⅱ (medium)
题目:题解:本题与46.全排列的区别在于不能出现重复的全排列,我们可以利用set在去掉重复的全排列,然而这样做的效率并不高,因为我们总是在寻找到一个完整的全排列后,再判断是否这个全排列重复添加到result中。那么请思考该如何优化呢?我们的优化方案是在回溯的过程需要剪枝:针对同一层次的计算,对连续的相同的元素只选取一个进行后续的替换,即可等价于基础全排列。例如,当前层次是[1,2, 1...原创 2019-11-03 21:02:19 · 324 阅读 · 0 评论 -
[回溯]leetcode51:N皇后(hard)
题目:51.N皇后题解:本题是回溯算法的经典例题,回溯算法是一种思想,它通常用递归实现。通常我们的回溯通过dfs(递归)实现,但是请务必清楚一点,dfs只是实现回溯算法的一种方法,它通常伴随着剪枝等一系列优化方案(这个是很玄学的,不作过多讨论)。回溯算法的时间复杂度通常是很高的,本题中的N皇后问题,节点总数为 n + n^2 + n^3 + ... + n^n,不超过 O(n^(n+1...原创 2019-11-01 16:58:56 · 232 阅读 · 0 评论 -
[回溯]leetocde90:子集 Ⅱ (medium)
题目:题解:回溯法本题与78.子集的区别在于nums中存在重复元素,也就是生成的子集会重复,所以我们使用仿照44.全排列 Ⅱ的剪枝手法来进行剪枝:针对同一层次的计算,对连续的相同的元素只选取一个进行后续的替换,即可等价于基础子集问题。代码如下:class Solution {public: vector<vector<int>> subsets...原创 2019-11-12 23:03:17 · 208 阅读 · 0 评论 -
[回溯]leetcode52:N皇后 Ⅱ (hard)
题目:52.N皇后 Ⅱ题解:本题在51.N皇后基础上直接返回所有可行皇后的个数。代码如下:class Solution {public: int totalNQueens(int n) { vector<string> board(n,string(n,'.'));//棋盘 vector<vector<string...原创 2019-11-11 20:07:13 · 175 阅读 · 0 评论 -
[回溯][康托展开法]leetcode60:第k个排列(medium)
题目:题解:题解1:回溯法本题自然而然地想到用回溯法解决,然而k值过大时,导致超时了,所以使用解法2的数学方法。题解2:康托展开康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。对于n=3,k=3,我们将k减1(k--)表示k之前有k-1个排列,然后用2 / (3-1)! =1 余...原创 2019-11-11 22:09:20 · 231 阅读 · 0 评论 -
[回溯]leetocde77:组合(medium)
题目:题解:回溯法本题与全排列的区别在于全排列中会出现[1,2]、[2,1]这样的排列,然而在组合中是不能存在的,所以我们每次需要将组合数第一个数固定,然后组合数之后的数依次增大。代码如下:class Solution {public: vector<vector<int>> combine(int n, int k) { ve...原创 2019-11-11 23:43:44 · 215 阅读 · 0 评论 -
[回溯][二进制枚举]leetcode78:子集(medium)
题目:题解:题解1:暴力法直接从前遍历,遇到一个数就把所有子集加上该数组成新的子集,遍历完毕即是所有子集题解2:回溯法与77.组合的算法思想一样,发现共性便可求解。代码如下:class Solution {public: //解法1:暴力法,直接从前遍历,遇到一个数就把所有子集加上该数组成新的子集,遍历完毕即是所有子集 vector<vecto...原创 2019-11-12 22:40:58 · 262 阅读 · 0 评论 -
[回溯]leetcode79:单词搜索(medium)
题目:题解:本题又是一道回溯法经典练习题,212.单词搜索 Ⅱ是使用前缀树+回溯法解决的,而本题难度相对而言小一点,直接使用回溯法就好了。代码如下:class Solution {public: bool exist(vector<vector<char>>& board, string word) { for(int x=0...原创 2019-11-13 11:16:42 · 180 阅读 · 0 评论 -
[回溯][镜像反射]leetcode89:格雷编码(medium)
题目:题解:题解1:迭代法,思路较清晰,直接看代码就好了题解2:镜像反射法题解3:回溯法(说实话,这个回溯法把我也搞蒙了,贴贴大佬的代码吧,有时间再看)代码如下:class Solution {public: //题解1:迭代法,思路较清晰 vector<int> grayCode_1(int n) { if(n==0)retur...原创 2019-11-18 22:18:28 · 301 阅读 · 0 评论 -
[回溯]leetcode93:复原IP地址(medium)
题目:题解:回溯法:ip地址有三个点,分为四段,每段的数字范围必须在[0,255]内,注意0只能作为单独一个段,比如:0.0.0.124变量介绍:flag来表示4个段,track表示决策路径(也就是可生成的ip地址),其他变量大家看代码就懂了。代码如下:class Solution {public: vector<string> restoreIpAddr...原创 2019-11-20 15:18:38 · 313 阅读 · 1 评论 -
[dfs+dp][回溯]leetcode131:分割回文串(medium)
题目:题解:解法1:dfs+dp先建立dp数组,与5.最长回文子串算dp数组一样,然后就是dfs寻找所有的可行解了。解法3:回溯法思想与N皇后的回溯法差不多的模板,寻找到所有的可行解后,回溯完成!题解①代码:class Solution {private: vector<vector<string>> result; vect...原创 2019-11-02 20:56:56 · 244 阅读 · 0 评论 -
[回溯法]leetcode282:给表达式添加运算符(hard)
题目:282.给表达式添加运算符题解:回溯法本题最难最难的就是处理乘法了,由于乘法的优先级比加、减法高,所以在遇到乘号时需要回退到上一步,然后将上一步的操作数与乘法进行运算。比如:num = “232”,target = 8,在计算完2+3=5后,我们在3后面添加*2,然而*的优先级高,所以我们需要返回到上一步val(5)-mult(3)=2,然后计算上一步的结果与乘法运算的结果2...原创 2019-11-24 00:05:12 · 389 阅读 · 0 评论