回溯算法

(4 封私信 / 6 条消息) 回溯算法 - 搜索结果 - 知乎 (zhihu.com)这个回答的角度挺好的

回溯算法的解决问题类型

  • 组合问题:N个数⾥⾯按⼀定规则找出k个数的集合
  • 切割问题:⼀个字符串按⼀定规则有⼏种切割⽅式
  • ⼦集问题:⼀个N个数的集合⾥有多少符合条件的⼦集
  • 排列问题:N个数按⼀定规则全排列,有⼏种排列⽅式
  • 棋盘问题:N皇后,解数独等等

回溯算法的理解

  回溯的过程从入递归出递归理解。

  回溯法解决的问题都可以抽象为树形结构,是的,我指的是所有回溯法的问题都可以抽象为树形结构! 因为回溯法解决的都是在集合中递归查找⼦集,集合的⼤⼩就构成了树的宽度,递归的深度,都构成的 树的深度。

      这个树可以称之为决策树,每一个节点都是一个决策点,在每一个节点选择不同的树枝,树枝表示从数组中选择出来的值,满足条件则加入到结果集合中。

      在递归的过程中,递归就是进入下一层节点,进入递归前,选择树枝就是做选择,出递归时需要把路径中上一条树枝清除,回归上一层的状态。

  回溯三部曲:

      1、回溯函数模板返回值以及参数的确定

                回溯算法中函数返回值⼀般为void。再来看⼀下参数,因为回溯算法需要的参数可不像⼆叉树递归的时候那么容易⼀次性确定下来,所     以一般是先写逻辑,然后需要什么参数,就填什么参数。

      2、回溯终止的条件

           ⼀般来说搜到叶⼦节点了,也就找到了满⾜条件的⼀条答 案,把这个答案存放起来,并结束本层递归。

      3、回溯搜索的遍历过程

    回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度

             

for (选择:本层集合中元素(树中节点孩⼦的数量就是集合的⼤⼩)) {
 处理节点;
 backtracking(路径,选择列表); // 递归
 回溯,撤销处理结果
}

 也可以这样看

result = []
def backtrack(路径, 选择列表):
    if 满足结束条件:
        result.add(路径)
        return

    for 选择 in 选择列表:   // 在一层中做选择, (理解为i表示一层中的第i个节点)
        做选择
        backtrack(路径, 选择列表)
        撤销选择

 递归与回溯的区别:

  •  递归相当于一条路走到黑,途中错误了不用返回上一层;
  • 回溯利用递归实现,但是在递归的途中某一节点不对时,需要返回上一个节点的状态

根据题目中需要遍历所有的情况时,可以直接使用递归而不需要回溯,如leetcode22

 

 

 

  

 

posted @ 2021-09-01 10:02  CharonKK  阅读(108)  评论(0)    收藏  举报