DFS,回溯,栈及BFS

DFS框架

DFS顾名思义是种搜索算法,深度优先,而回溯是DFS过程中的必备操作,因为

  • 假如你是搜索一个解:达到这个深度无法找到搜索目标你就需要回溯换条路找解,
  • 假如你搜索的是多个解:要么你剪枝你就需要回溯,要么找到一个解需要回溯去找另外的解

回溯过程中需要标记,怎么做标记呢?我们需要栈(递归,也就是函数调用自身自然而然形成栈)

下面是通用的框架:

void DFS(i)
{
  1. 标记i
  2. 做些事情:比如输出或者return等等
  3. 每个i邻接点j:if(未标记||剪枝) DFS(j)
}

我这里的邻接点要放开来想,树和图的邻接点很好想就很直接。那假如是迷宫那就是上下左右,假如N皇后当前行的每一列,假如是生成子集就是当前字符选和不选,思维要扩展
标记i和判断是否标记,这种一般用于类似于图结构,因为不同的点可能拥有相同的邻接点,回溯回来可能会再次相遇

void DFS(i)
{
  1. 做些事情:比如输出或者return等等
  2. 每个i邻接点j: if(剪枝) DFS(j)
}

而类似于树的就不需要标记,因为回溯过程中直接扔掉,之后不会再见面了。上面的N皇后和生成子集就是用的这个,道理很简单,因为他们的解空间是棵树,所以不用标记啦

个人愚见


BFS框架

广度优先,需要用栈

void BFS()
{

  初始化并标记某些入队
  while (队列不空) {
  	1. 队头出队
  	2. 做些事情:比如输出或者return等等
  	3. 每个邻接点:if(未标记) {入队;标记;}
  }
}

类似DFS,树的就不需要标记。

void BFS()
{

  初始化某些入队
  while (队列不空) {
  	1. 队头出队
  	2. 做些事情:比如输出或者return等等
  	3. 每个邻接点:入队
  }
}


DFS和BFS框架的题目,只要看出本质就能按照框架写出,简单的题其实不要想太多,框架一上就ok

裸的很多很多

104. 二叉树的最大深度
107. 二叉树的层次遍历 II

需要建图
5354. 通知所有员工所需的时间

207. 课程表

127. 单词接龙


需要用些高级的数据结构
407. 接雨水 II

发布了178 篇原创文章 · 获赞 140 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_42146775/article/details/104340994
今日推荐