应对笔试手写代码,如何准备深度优先算法 & 广度优先算法?
Posted 执章学长
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应对笔试手写代码,如何准备深度优先算法 & 广度优先算法?相关的知识,希望对你有一定的参考价值。
应对笔试手写代码,如何准备深度优先算法 & 广度优先算法?
- 1. 什么是深度优先算法?什么又是广度优先算法?
- 2. 广度优先算法使用场景
- 3. 广度优先算法模板
- 4. 深度优先算法使用场景
- 5. 深度优先算法模板
- 6. BFS 和 DFS 的复杂度
- 7. BFS 和 DFS 实现方式
1. 什么是深度优先算法?什么又是广度优先算法?
这么高大上的名字,听起来是不是一脸懵逼,别着急,我给大家举一个通俗的例子,不知道大家有没有看过《小蝌蚪找妈妈》的故事,现在我就用这个例子给大家解释。
下面我画的图优点丑,不过可以凑合看。
上面小蝌蚪在0号位置,它想找他的母亲可能出现在最后一层,那么小蝌蚪可以怎么走呢?
如果是按照广度优先搜索,小蝌蚪可以按照每一层找路径,最后,查找的结果就是#0#1#2#3#4#5…
如果是按照深度优先搜索,小蝌蚪可以按照一条路线走到底,走完后再返回原来的分叉点,选择别的路继续走,直到走完。查找的结果是#0#2#6#14#13#5#12#11#1#4#10…
(ps:深度优先算法也叫做DFS,广度优先算法也叫做BFS)
2. 广度优先算法使用场景
1、连通块问题
包括图、树、二维数组(矩阵)等等,即通过一个点扩散,找到一整个连通块。
2、层次遍历
给你一棵树,按每一层输出。
给你一个简单图(无方向、无权重),求最短路径。(其实和树的遍历是一样的,只不过图可能会遍历到重复节点,我们只需要每次去重即可,最后取最先到达目标节点时的层数即可)。
3、拓扑排序
给你一个当方向的图,求出他的拓扑排序,或者问是否有拓扑排序,或者求拓扑排序中最小的,或者问是否唯一(本质是一样的)。经典的问题就是说上某一节课之前需要上另一节课,现在给你若干课程并且有些课需要其他课线上才行,问你应该怎么安排课程。此时你把科目画出来,加上方向,就是拓扑问题了。
3. 广度优先算法模板
class Solution
public List<List<Integer>> levelOrder(TreeNode root)
List<List<Integer>> res = new ArrayList<>();
if(root == null)
return res;
// 1. 定义队列
Queue<TreeNode> queue = new LinkedList<>();
// 2.加入初始条件
queue.offer(root);
// 3. 队列不为空的while循环
while(!queue.isEmpty())
List<Integer> oneRes = new ArrayList<>();
int n = queue.size();
// 3.1 for循环将队列元素逐一取出进行处理
for(int i = 0;i < n;++i)
TreeNode temp = queue.poll();
// 3.0 业务处理
oneRes.add(temp.val);
// 3.2 将下一条件放入队列中
if(temp.left!=null)
queue.offer(temp.left);
if(temp.right!=null)
queue.offer(temp.right);
// 3.3 将符合条件的一种结果放入结果集中
res.add(oneRes);
// 4. 返回结果集
return res;
另外,关于二叉树的序列化和反序列化问题,也可以用广度优先算法来实现,如果题目指定使用哪种方法,广度优先算法序列化会比深度优先算法更直观。
4. 深度优先算法使用场景
1、图或者树的遍历(包括二叉树的遍历、连通图等)(有时候并不是明显的图或者树,而是需要自己手动模拟树或者图)。
2、排列(给定一些元素,返回所有可能的排列)(例如(1、2、3),排列有(123)(132)(213)(231)(312)(321))。
3、组合(给定一些元素,返回所有可能的组合)(例如(1、2、3),组合有(空)(1)(2)(3)(12)(13)(23)(123))。
在操作排列组合的时候,有时候会有重复的元素导致结果重复,除了用 HashSet 去重外,使用选代表的方法更合适,选代表就是选出一个合适的代表,其余重复元素直接忽略。
5. 深度优先算法模板
//模板2
void dfs()//参数用来表示状态
if(到达终点状态)
...//根据题意添加
return;
if(越界或者是不合法状态)
return;
if(特殊状态)//剪枝
return ;
for(扩展方式)
if(扩展方式所达到状态合法)
修改操作;//根据题意来添加
标记;
dfs();
(还原标记);
//是否还原标记根据题意
//如果加上(还原标记)就是 回溯法
6. BFS 和 DFS 的复杂度
时间复杂度都是:O(V+E),V为顶点个数,E为边个数
BFS 的空间复杂度为队列大小,与宽度有关。
DFS 的空间复杂度为调用递归时的占用空间,与深度有关。
7. BFS 和 DFS 实现方式
BFS 一般是通过队列实现。
DFS 一般是通过递归实现。
以上是关于应对笔试手写代码,如何准备深度优先算法 & 广度优先算法?的主要内容,如果未能解决你的问题,请参考以下文章