彻底搞懂回溯法(本文真的很详细)

14 篇文章 30 订阅
订阅专栏

目录

回溯法理论基础

组合问题

组合问题

组合总和

组合总和(一)

组合总和(二)

组合总和(三)(本题去重特别重要)

多个集合求组合

切割问题

子集问题

子集问题(一)

子集问题(二)

递增子序列

排列问题

排列问题(一)

排列问题(二)

去重问题

重新安排行程(图论额外拓展)

棋盘问题

N皇后问题

解数独问题

性能分析


 转载于: https://zhuanlan.zhihu.com/p/302415065(知乎)

「leetcode」最强回溯算法总结篇!历时21天、画了20张树形结构图、14道精选回溯题目精讲_代码随想录的博客-CSDN博客

回溯法理论基础

「回溯是递归的副产品,只要有递归就会有回溯」,所以回溯法也经常和二叉树遍历,深度优先搜索混在一起,因为这两种方式都是用了递归。

回溯法就是暴力搜索,并不是什么高效的算法,最多再剪枝一下。

回溯算法能解决如下问题:

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 棋盘问题:N皇后,解数独等等

回溯法确实不好理解,所以需要把回溯法抽象为一个图形来理解就容易多了,「在后面的每一道回溯法的题目我都将遍历过程抽象为树形结构方便大家的理解」

在 关于回溯算法,你该了解这些!还用了回溯三部曲来分析回溯算法,并给出了回溯法的模板:

//一定要分成横纵两个方面思考回溯
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {//注意i=0,i=start的区别
        处理节点;
        backtracking(路径,选择列表); // 递归  注意(i)和(i++)的区别  后面会懂
        回溯,撤销处理结果
    }
}

组合问题

组合问题

(组合问题就是将若干个数组合在一起构成答案)

在 回溯算法:求组合问题!中,我们开始用回溯法解决第一道题目:组合问题。

我在文中开始的时候给大家列举k层for循环例子,进而得出都是同样是暴利解法,为什么要用回溯法!

「此时大家应该深有体会回溯法的魅力,用递归控制for循环嵌套的数量!」

本题我把回溯问题抽象为树形结构,如题:

可以直观的看出其搜索的过程:「for循环横向遍历,递归纵向遍历,回溯不断调整结果集」,这个理念贯穿整个回溯法系列,也是我做了很多回溯的题目,不断摸索其规律才总结出来的。

对于回溯法的整体框架,网上搜的文章这块都说不清楚,按照天上掉下来的代码对着讲解,不知道究竟是怎么来的,也不知道为什么要这么写。

优化回溯算法只有剪枝一种方法,在 回溯算法:组合问题再剪剪枝中把回溯法代码做了剪枝优化,树形结构如图:

大家可以一目了然剪的究竟是哪里。

「 回溯算法:求组合问题!剪枝精髓是:for循环在寻找起点的时候要有一个范围,如果这个起点到集合终止之间的元素已经不够题目要求的k个元素了,就没有必要搜索了」

「在for循环上做剪枝操作是回溯法剪枝的常见套路!」 后面的题目还会经常用到。

组合总和

组合总和(一)

在 回溯算法:求组合总和!中,相当于  回溯算法:求组合问题!加了一个元素总和的限制。

树形结构如图:

整体思路还是一样的,本题的剪枝会好想一些,即:「已选元素总和如果已经大于n(题中要求的和)了,那么往后遍历就没有意义了,直接剪掉」,如图:

在本题中,依然还可以有一个剪枝,就是 回溯算法:组合问题再剪剪枝中提到的,对for循环选择的起始范围的剪枝。

所以剪枝的代码可以在for循环加上 i <= 9 - (k - path.size()) + 1 的限制!

组合总和(二)

在 回溯算法:求组合总和(二)中讲解的组合总和问题,和 回溯算法:求组合问题!, 回溯算法:求组合总和!和区别是:本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。

不少同学都是看到可以重复选择,就义无反顾的把startIndex去掉了。

「本题还需要startIndex来控制for循环的起始位置,对于组合问题,什么时候需要startIndex呢?」

我举过例子,如果是一个集合来求组合的话,就需要startIndex,例如: 回溯算法:求组合问题!, 回溯算法:求组合总和!。

如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如: 回溯算法:电话号码的字母组合

(也就是说如果(3,2)和(2,3)不一样就用startindex去重,或者题目要求一个数只能用一遍也用startindex去重)。 

「注意以上我只是说求组合的情况,如果是排列问题,又是另一套分析的套路」

树形结构如下:

最后还给出了本题的剪枝优化,如下:

for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++)

优化后树形结构如下:

组合总和(三)(本题去重特别重要)

在 回溯算法:求组合总和(三)中集合元素会有重复,但要求解集不能包含重复的组合。

「所以难就难在去重问题上了」。(本题注意数组含有重复元素)

如果原数组有相同的元素,则用本题方法去重

这个去重问题,相信做过的录友都知道有多么的晦涩难懂。网上的题解一般就说“去掉重复”,但说不清怎么个去重,代码一甩就完事了。

为了讲解这个去重问题,「Carl自创了两个词汇,“树枝去重”和“树层去重”」

都知道组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上“使用过”,一个维度是同一树层上“使用过”。「没有理解这两个层面上的“使用过” 是造成大家没有彻底理解去重的根本原因」

我在图中将used的变化用橘黄色标注上,「可以看出在candidates[i] == candidates[i - 1]相同的情况下:」

  • used[i - 1] == true,说明同一树支candidates[i - 1]使用过
  • used[i - 1] == false,说明同一树层candidates[i - 1]使用过

「这块去重的逻辑很抽象,网上搜的题解基本没有能讲清楚的,如果大家之前思考过这个问题或者刷过这道题目,看到这里一定会感觉通透了很多!」

对于去重,其实排列和子集问题也是一样的道理。

多个集合求组合

在 回溯算法:电话号码的字母组合中,开始用多个集合来求组合,还是熟悉的模板题目,但是有一些细节。

例如这里for循环,可不像是在  回溯算法:求组合问题!和 回溯算法:求组合总和!中从startIndex开始遍历的。

「因为本题每一个数字代表的是不同集合,也就是求不同集合之间的组合,而 回溯算法:求组合问题!和 回溯算法:求组合总和!都是是求同一个集合中的组合!」

树形结构如下:

如果大家在现场面试的时候,一定要注意各种输入异常的情况,例如本题输入1 * #按键。

其实本题不算难,但也处处是细节,还是要反复琢磨。

切割问题

在 回溯算法:分割回文串中,我们开始讲解切割问题,虽然最后代码看起来好像是一道模板题,但是从分析到学会套用这个模板,是比较难的。

我列出如下几个难点:

  • 切割问题其实类似组合问题
  • 如何模拟那些切割线
  • 切割问题中递归如何终止
  • 在递归循环中如何截取子串
  • 如何判断回文

如果想到了「用求解组合问题的思路来解决 切割问题本题就成功一大半了」,接下来就可以对着模板照葫芦画瓢。

「但后序如何模拟切割线,如何终止,如何截取子串,其实都不好想,最后判断回文算是最简单的了」

所以本题应该是一个道hard题目了。

除了这些难点,「本题还有细节,例如:切割过的地方不能重复切割所以递归函数需要传入i + 1」

树形结构如下:

子集问题

讲简单一点就是边递归边存值的问题。

子集问题(一)

在 回溯算法:求子集问题!中讲解了子集问题,「在树形结构中子集问题是要收集所有节点的结果,而组合问题是收集叶子节点的结果」

如图:

认清这个本质之后,今天的题目就是一道模板题了。

「本题其实可以不需要加终止条件」,因为startIndex >= nums.size(),本层for循环本来也结束了,本来我们就要遍历整颗树。

有的同学可能担心不写终止条件会不会无限递归?

并不会,因为每次递归的下一层就是从i+1开始的。

如果要写终止条件,注意:result.push_back(path);要放在终止条件的上面,如下:

result.push_back(path); // 收集子集,要放在终止添加的上面,否则会漏掉结果
if (startIndex >= nums.size()) { // 终止条件可以不加
    return;
}

子集问题(二)

在 回溯算法:求子集问题(二)中,开始针对子集问题进行去重。

本题就是 回溯算法:求子集问题!的基础上加上了去重,去重我们在 回溯算法:求组合总和(三)也讲过了,一样的套路。

树形结构如下:

递增子序列

在 回溯算法:递增子序列中,处处都能看到子集的身影,但处处是陷阱,值得好好琢磨琢磨!

树形结构如下:

很多同学都会把这道题目和 回溯算法:求子集问题(二)混在一起。

「 回溯算法:求子集问题(二)也可以使用set针对同一父节点本层去重,但子集问题一定要排序,为什么呢?」

我用没有排序的集合{2,1,2,2}来举个例子画一个图,如下:

「相信这个图胜过千言万语的解释了」

排列问题

排列问题(一)

回溯算法:排列问题! 又不一样了。

排列是有序的,也就是说[1,2] 和[2,1] 是两个集合,这和之前分析的子集以及组合所不同的地方。

可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。

如图:

「大家此时可以感受出排列问题的不同:」

  • 每层都是从0开始搜索而不是startIndex
  • 需要used数组记录path里都放了哪些元素了

排列问题(二)

排列问题也要去重了,在 回溯算法:排列问题(二)中又一次强调了“树层去重”和“树枝去重”。

树形结构如下:

「这道题目神奇的地方就是used[i - 1] == false也可以,used[i - 1] == true也可以!」

我就用输入: [1,1,1] 来举一个例子。

树层上去重(used[i - 1] == false),的树形结构如下:

树枝上去重(used[i - 1] == true)的树型结构如下:

「可以清晰的看到使用(used[i - 1] == false),即树层去重,效率更高!」

本题used数组即是记录path里都放了哪些元素,同时也用来去重,一举两得。

去重问题

以上我都是统一使用used数组来去重的,其实使用set也可以用来去重!

在 本周小结!(回溯算法系列三)续集中给出了子集、组合、排列问题使用set来去重的解法以及具体代码,并纠正一些同学的常见错误写法。

同时详细分析了 使用used数组去重 和 使用set去重 两种写法的性能差异:

「使用set去重的版本相对于used数组的版本效率都要低很多」,大家在leetcode上提交,能明显发现。

原因在 回溯算法:递增子序列中也分析过,主要是因为程序运行的时候对unordered_set 频繁的insert,unordered_set需要做哈希映射(也就是把key通过hash function映射为唯一的哈希值)相对费时间,而且insert的时候其底层的符号表也要做相应的扩充,也是费时的。

「而使用used数组在时间复杂度上几乎没有额外负担!」

「使用set去重,不仅时间复杂度高了,空间复杂度也高了」,在 本周小结!(回溯算法系列三)中分析过,组合,子集,排列问题的空间复杂度都是O(n),但如果使用set去重,空间复杂度就变成了O(n^2),因为每一层递归都有一个set集合,系统栈空间是n,每一个空间都有set集合。

那有同学可能疑惑 用used数组也是占用O(n)的空间啊?

used数组可是全局变量,每层与每层之间公用一个used数组,所以空间复杂度是O(n + n),最终空间复杂度还是O(n)。

重新安排行程(图论额外拓展)

之前说过,有递归的地方就有回溯,深度优先搜索也是用递归来实现的,所以往往伴随着回溯。

在 回溯算法:重新安排行程其实也算是图论里深搜的题目,但是我用回溯法的套路来讲解这道题目,算是给大家拓展一下思路,原来回溯法还可以这么玩!

以输入:[["JFK", "KUL"], ["JFK", "NRT"], ["NRT", "JFK"]为例,抽象为树形结构如下:

本题可以算是一道hard的题目了,关于本题的难点我在文中已经详细列出。

「如果单纯的回溯搜索(深搜)并不难,难还难在容器的选择和使用上!」

本题其实是一道深度优先搜索的题目,但是我完全使用回溯法的思路来讲解这道题题目,「算是给大家拓展一下思维方式,其实深搜和回溯也是分不开的,毕竟最终都是用递归」

棋盘问题

N皇后问题

在 回溯算法:N皇后问题中终于迎来了传说中的N皇后。

下面我用一个3 * 3 的棋牌,将搜索过程抽象为一颗树,如图:

从图中,可以看出,二维矩阵中矩阵的高就是这颗树的高度,矩阵的宽就是树形结构中每一个节点的宽度。

那么我们用皇后们的约束条件,来回溯搜索这颗树,「只要搜索到了树的叶子节点,说明就找到了皇后们的合理位置了」

如果从来没有接触过N皇后问题的同学看着这样的题会感觉无从下手,可能知道要用回溯法,但也不知道该怎么去搜。

「这里我明确给出了棋盘的宽度就是for循环的长度,递归的深度就是棋盘的高度,这样就可以套进回溯法的模板里了」

相信看完本篇 回溯算法:N皇后问题也没那么难了,传说已经不是传说了,哈哈。

解数独问题

在 回溯算法:解数独中要征服回溯法的最后一道山峰。

解数独应该是棋盘很难的题目了,比N皇后还要复杂一些,但只要理解 “二维递归”这个过程,其实发现就没那么难了。

大家已经跟着「代码随想录」刷过了如下回溯法题目,例如: 77.组合(组合问题), 131.分割回文串(分割问题), 78.子集(子集问题), 46.全排列(排列问题),以及 51.N皇后(N皇后问题),其实这些题目都是一维递归。

其中 N皇后问题是因为每一行每一列只放一个皇后,只需要一层for循环遍历一行,递归来遍历列,然后一行一列确定皇后的唯一位置。

本题就不一样了,「本题中棋盘的每一个位置都要放一个数字,并检查数字是否合法,解数独的树形结构要比N皇后更宽更深」

因为这个树形结构太大了,我抽取一部分,如图所示:

解数独可以说是非常难的题目了,如果还一直停留在一维递归的逻辑中,这道题目可以让大家瞬间崩溃。

「所以我在 回溯算法:解数独中开篇就提到了二维递归,这也是我自创词汇」,希望可以帮助大家理解解数独的搜索过程。

一波分析之后,在看代码会发现其实也不难,唯一难点就是理解「二维递归」的思维逻辑。

「这样,解数独这么难的问题也被我们攻克了」

性能分析

「关于回溯算法的复杂度分析在网上的资料鱼龙混杂,一些所谓的经典面试书籍不讲回溯算法,算法书籍对这块也避而不谈,感觉就像是算法里模糊的边界」

「所以这块就说一说我个人理解,对内容持开放态度,集思广益,欢迎大家来讨论!」

以下在计算空间复杂度的时候我都把系统栈(不是数据结构里的栈)所占空间算进去。

子集问题分析:

  • 时间复杂度:O(n * 2^n),因为每一个元素的状态无外乎取与不取,所以时间复杂度为O(2^n),构造每一组子集都需要填进数组,又有需要O(n),最终时间复杂度:O(n * 2^n)
  • 空间复杂度:O(n),递归深度为n,所以系统栈所用空间为O(n),每一层递归所用的空间都是常数级别,注意代码里的result和path都是全局变量,就算是放在参数里,传的也是引用,并不会新申请内存空间,最终空间复杂度为O(n)

排列问题分析:

  • 时间复杂度:O(n!),这个可以从排列的树形图中很明显发现,每一层节点为n,第二层每一个分支都延伸了n-1个分支,再往下又是n-2个分支,所以一直到叶子节点一共就是 n * n-1 * n-2 * ..... 1 = n!。
  • 空间复杂度:O(n),和子集问题同理。

组合问题分析:

  • 时间复杂度:O(n * 2^n),组合问题其实就是一种子集的问题,所以组合问题最坏的情况,也不会超过子集问题的时间复杂度。
  • 空间复杂度:O(n),和子集问题同理。

N皇后问题分析:

  • 时间复杂度:O(n!) ,其实如果看树形图的话,直觉上是O(n^n),但皇后之间不能见面所以在搜索的过程中是有剪枝的,最差也就是O(n!),n!表示n * (n-1) * .... * 1。
  • 空间复杂度:O(n),和子集问题同理。

解数独问题分析:

  • 时间复杂度:O(9^m) , m是'.'的数目。
  • 空间复杂度:O(n^2),递归的深度是n^2

「一般说道回溯算法的复杂度,都说是指数级别的时间复杂度,这也算是一个概括吧!」

回溯法基础知识
Jayphone17的博客
11-05 2824
回溯法是一种选优搜索法,按照选优条件进行深度优先搜索(简单来讲就是遍历)。当搜索进行到某一步时,发现原先选择并不是最优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术称为回溯法,而满足回溯条件的某个状态点称为“回溯点”。 1.算法思想 回溯法是从初始状态出发,按照深度优先搜索得到方式,根据产生子节点的条件约束,搜索问题的解。当发现当前结点不满足求解条件时,就回溯,尝试其他...
回溯算法讲解
11-28
回溯算法讲解
回溯法详细讲解,有很多例子
12-31
本文档对回溯法进行详细讲解,通俗易懂,举例很多 回溯法,就是试探法,按照优选条件去向前搜索,以达到目标。但是在搜索到某一步时,发现原先这样并不能满足条件,就回退一步重新选择,这种走不通就退回再走的技术成为回溯法。在做回溯法的题目的时候,有添加状态或元素就一定有与之对应的回退状态和元素。若是寻找成功,回退以查看有没有其他满足条件的解;如果寻找不成功,回退以查看其它情况。
C++回溯法实例分析
01-20
本文实例讲述了C++回溯法,分享给大家供大家参考之用。具体方法分析如下: 一般来说,回溯法是一种枚举状态空间中所有可能状态的系统方法,它是一个一般性的算法框架。 解向量a=(a1, a2, …, an),其中每个元素ai取自一个有限序列集Si,这样的解向量可以表示一个排列,其中ai是排列中的第i个元素,也可以表示子集S,其中ai为真当且仅当全集中的第i个元素在S中;甚至可以表示游戏的行动序列或者图中的路径。 在回溯法的每一步,我们从一个给定的部分解a={a1, a2, …, ak}开始,尝试在最后添加元素来扩展这个部分解,扩展之后,我们必须测试它是否为一个完整解,如果是的话,就输出这个解;如
算法入门6:回溯法
热门推荐
JarvisChu的专栏
11-13 9万+
一. 回溯法 – 深度优先搜素                        1. 简单概述 回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解或者最优解。 基本思想类同于: 图的深度优先搜索二叉树的后序遍历 【 分支限界法:广度优先搜索 思想类同于:图的广度优先遍历 二叉树的层序
C++基于回溯法解决八皇后问题示例
12-31
本文实例讲述了C++基于回溯法解决八皇后问题的方法。分享给大家供大家参考,具体如下: 回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法适用于解一些组合数相当大的问题。 回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。 回溯法指导思想——走不通,就掉头。设计过程:确定问题的解空间;确定结点的扩展规则;搜索。 n皇后问题 要在n*n的国际象棋棋盘中放n个皇后,使任意
回溯法解决数独问题-2.docx
01-27
回溯法解决数独问题-2.docx
回溯法
weixin_34109408的博客
09-30 248
写法分类: --|递归:代码简便,耗费资源 --|迭代 :相反 解空间分类: --|子集树 所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间成为子集树。如0-1背包问题,从所给重量、价值不同的物品中挑选几个物品放入背包,使得在满足背包不超重的情况下,背包内物品价值最大。它的解空间就是一个典型的子集树。 递归表达 void...
回溯算法详解(Back Tracking)
武梓龙 廊坊师范学院信息技术提高班 十七期
07-15 1778
因为它需要穷举所有可能的解空间。在最坏情况下,回溯法的时间复杂度为指数级别,即O(2^n),其中n为问题的规模。然而,回溯法的效率和稳定性可能受到问题规模的影响。对于规模较大的问题,回溯法可能会耗费大量的时间和空间。回溯法,可以系统的搜索一个问题的所有解或任一解。回溯法通常涉及到对问题状态的深度优先搜索,在搜索过程中,算法尝试一步步地构建解决方案,每次决策都会将问题状态。它通过穷举所有可能的解空间来搜索解,因此在给定的问题中,回溯法能够找到。因此,回溯法的空间复杂度通常是O(n),其中n为问题的规模。
五大算法思想(三)回溯法及常见例子
HK的博客
07-22 9236
五大算法思想 回溯法 八皇后问题、装载问题、批量作业调度问题、背包问题
递归与回溯4:一文彻底理解回溯
纵横千里 捭阖四方 的专栏
01-13 5237
1.回溯大白话 关于回溯,先用大白话说几个结论: 1.回溯能干什么? 主要解决那些暴力枚举也无法解决的问题。 2.回溯与递归是什么关系? 回溯是递归的纵横拓展,主要是递归(纵)+局部暴力枚举(横)。所以你可以从递归和暴力两个方面来拆解回溯问题。 3.回溯的关键在于“回”上,也就是要撤销,为什么要撤销? 因为回溯本质上仍然是枚举,你不喜欢她的前任,你要将她前任的所有东西都仍然,然后才愿意重新开始! 4.回溯经常看到“剪枝”,什么是剪枝,为什么要剪枝? 剪枝就是去掉那些不必要的递归,从而提高执
Python基于回溯法解决01背包问题实例
09-21
主要介绍了Python基于回溯法解决01背包问题,结合实例形式分析了Python回溯法采用深度优先策略搜索解决01背包问题的相关操作技巧,需要的朋友可以参考下
回溯算法及其应用
m0_72379992的博客
10-15 951
回溯算法是一种常用于解决组合优化问题、搜索问题和决策问题的算法。事实上,回溯正是的副产物,回溯算法就是通过递归实现的算法。他通过遍历所有情况来找到问题的解,若当前方案不可行,就会回溯(回退)并尝试其他可能的路径。和多层嵌套for循环相比,这种递归试错的方法不必设计的for循环,有效减轻了代码的复杂度,有利于算法在大规模的搜索空间中寻找最佳解决方案。回溯算法的本质是所有可能情况,虽然它的时间复杂度可能很高,但在许多复杂情况下,它仍然是一个可行的解决方案。
算法设计与分析之回溯法
qq_44075108的博客
12-04 9316
回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。为避免无效搜索,采用限界/剪枝函数;用约束函数(条件)在扩展结点处剪去不满足约束的子树,即剪去得不到可行解的子树;用目标函数剪去得不到最优解的子树。
回溯算法理解
bangxiangrong2576的博客
12-21 376
一、算法含义 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思路是:暴力算法的改进,在通过遍历所有路径基础上,通过回溯(往回找)筛除不可能的路径,提高效率。 二、解题步骤: 1.确定一个解空间,它包含问题的解;2.利用适于搜索的方法组织解空间;3.利用深度优先法搜索解空间;4.利用剪枝(约束函数、限界函数)避免移动到不可能产生解的子空间。 三、算法框架 ...
常用算法-回朔法
yixianfeng41的专栏
02-18 3170
1、概念回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用
回溯算法详解
Go-Hello的博客
07-29 641
回溯算法详解
牛客网刷题 | BC118 N个数之和
最新发布
m0_64000959的博客
06-09 488
目前主要分为三个专栏,后续还会添加: 专栏如下: C语言刷题解析 C语言系列文章 我的成长经历感谢阅读!初来乍到,如有错误请指出,感谢!输入数字N,然后输入N个数,计算这N个数的和。第一行输入一个整数N(0≤N≤50),第二行输入用空格分隔的N个整数。输出为一行,为第二行输入的“N个整数之和”的计算结果。使用数组的方式 先将用户输入的几个数字分别存起来定义一个变量将它数字的和加起来然后输出 代码 2 : 输入n个数相加,应该想到循
matlab 回溯算法
09-07
回溯算法是一种经典的算法思想,可以在给定的问题空间中搜索所有可能的解。在 MATLAB 中,你可以使用递归来实现回溯算法。 下面是一个简单的示例,演示了如何使用回溯算法解决一个典型的组合问题: ```matlab function backtrack(nums, path, result) if isempty(nums) result = [result; path]; return; end for i = 1:length(nums) num = nums(i); % 选择当前数字 path = [path, num]; % 递归搜索 backtrack(nums([1:i-1, i+1:end]), path, result); % 撤销选择 path = path(1:end-1); end end nums = [1, 2, 3]; path = []; result = []; backtrack(nums, path, result); disp(result); ``` 在这个示例中,我们传入一个数字数组 `nums`,一个当前路径 `path`,以及一个保存结果的数组 `result`。递归函数 `backtrack` 在每一步都会选择一个数字并继续递归搜索,直到没有数字可选择时,将当前路径添加到结果数组中。 请注意,在递归搜索之前需要将选择的数字添加到路径中,而在递归搜索之后需要撤销该选择,以便进行下一次尝试。这是回溯算法的核心思想。 以上示例仅仅是回溯算法的一个简单应用,实际问题可能会更加复杂。但是通过理解和掌握回溯算法的基本原理,你应该能够在 MATLAB 中应用回溯算法解决各种问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 彻底搞懂回溯法(本文真的很详细) 51289
  • c++ getline()详解 13357
  • 最全动态规划题型详解 5674
  • 什么是字节 字节和位的关系 4664
  • 详解五种最短路径算法及其区别(c++) 2922

分类专栏

  • 每日一题 3篇
  • 算法随笔 14篇

最新评论

  • 彻底搞懂回溯法(本文真的很详细)

    小恩同学Jack: 所以看完都没明白说了什么。

  • D3-八数码

    CSDN-Ada助手: 恭喜您发布了第20篇博客《D3-八数码》!能够坚持创作并且分享自己的见解,真的很值得称赞。希望您能继续保持这样的创作热情,不断进步。或许下一步可以尝试探讨一些与八数码相关的算法优化或者应用场景,让读者能够更深入地了解这个主题。期待您的下一篇作品!愿您的创作之路越走越宽广,不忘初心,砥砺前行。

  • D2-走迷宫

    CSDN-Ada助手: 恭喜你发布了新的博客“D2-走迷宫”!看到你持续创作,我感到非常开心。在这篇博客中,你用生动的语言描述了迷宫探险的过程,让读者仿佛也置身其中。希望你能继续保持写作的热情和创造力。或许下一步可以尝试写一些关于解谜游戏的心得体会,或者分享一些关于探险的趣闻。期待你更多精彩的作品!加油!

  • D1-n皇后

    CSDN-Ada助手: 算法 技能树或许可以帮到你:https://edu.csdn.net/skill/algorithm?utm_source=AI_act_algorithm

  • 彻底搞懂回溯法(本文真的很详细)

    没有对象的野指针2: 这是不是拿来主义

大家在看

  • AttributeError:‘LunarDate object has no attribute ‘getYearInGanZhi
  • 学习java第一百零一天

最新文章

  • D3-八数码
  • D2-走迷宫
  • D1-n皇后
2024年3篇
2022年17篇

目录

目录

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司运城网站优化公司鹤壁百度网站优化报价滨州百度网站优化价格防城港seo优化公司天水建站公司福州网站建设设计濮阳品牌网站设计哪家好民治建网站价格绵阳百姓网标王推广多少钱湘潭营销网站多少钱郴州关键词排名包年推广公司木棉湾百度竞价包年推广哪家好汕尾网站搭建公司醴陵网站推广系统报价焦作网站设计多少钱荆州建站价格衢州至尊标王公司坑梓百度网站优化排名价格和县网站搭建价格霍邱网站优化价格黔东南SEO按天计费哪家好喀什网站优化推广公司双龙建设网站报价布吉网站排名优化重庆优化报价永新百度seo宜宾网站开发报价伊犁关键词排名公司长葛网站建设推荐保山优化报价歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化