【C++】算法集锦(5):BFS算法
文章目录
- BFS算法框架
- 框架代码
- 简单题:二叉树的最小高度
- 拔高题:解开密码锁的最少次数
- 一波优化:双向BFS
BFS算法框架
BFS算法和DFS算法属于图论算法的范畴,DFS在前面回溯中,可以去看一下。
BFS算法用于寻找两点之间的最短路径。
碧如说:寻找树的最小高度(迭代法)、走迷宫、导航等问题。
这些问题看起来都会比较抽象,去做也是很抽象。
与其说算法框架难写,倒不如说是把实际问题转化为算法问题来的要难。
还记得我在图论算法那篇里面有讲过:学习图论算法,最难的是要有用图论算法的意识。等下看了例题就知道了。
框架代码
这个代码其实就是微调一下图的BFS遍历,搞成个伪代码的样子,没什么新鲜的。
int BFS(Node start,Node target){/*这是一个BFS算法的代码框架return:返回从start到target的最短步数start:起始点target:终点*/Queue<Node> q;Set<Node> visited; //避免走回头路q.offer(start); //将起点加入队列visited.add(start);int step = 0; //纪录扩散的步数while(q not empty){int sz = q.size();for(int i = 0; i<sz; i++){Node cur = q.poll();//判断是否到终点if(cur is target)return step;//将cur相邻节点加入队列for(Node x: cur.adj()) //cur.adj()泛指与cur相邻的节点if(x not in visited){q.offer(x);visited.add(x);}} step++; //更新步数}
}
简单题:二叉树的最小高度
不难吧,用递归的话一下就出来了。
不过现在不是在讲BFS嘛,那就用BFS的方法吧。
起点是什么?起点是根节点。终点是什么?终点就是最靠近根节点的、两个子节点都是Null的节点。
接下来,我们对上面的框架进行改造:
int minDepth(TreeNode root){/*这是一个求二叉树最小高度的函数return:二叉树的最小高度root:根节点*/if(root == NULL) return 0;Queue<TreeNode> q;q.offer(root); //将起点加入队列int depth = 1; while(!q.isEmpty()){int sz = q.size();for(int i = 0; i<sz; i++){TreeNode cur = q.poll();//判断是否到终点if(cur.left == NULL && cur.right == NULL)return depth;//将cur相邻节点加入队列if(cur.left != NULL)q.offer(cur.left);if(cur.right != NULL)q.offer(cur.right);} depth++; //更新步数}return depth;
}
拔高题:解开密码锁的最少次数
你有一个带有四个圆盘拨轮的轮盘锁,每个拨轮都有“0-9”十个数字,旋转没有边界限制,但是每次只能旋转一个位置。轮盘锁的初始位置是“0000”,现在给你一个密码和一组死亡密码(避免拨出的密码),请你设计一个算法,计算从初始状态到拨出最终密码所需要的最少次数。
抽象吧,就直接看这个题目,直接给我干懵逼了。
但是,不怕啊,前面不是说过了动态规划类题目的解题步骤嘛,先把暴力解法画出来,走通一条路,再优化。
那,暴力解法怎么解?真的,要不是有那个“死亡密码组”的存在,还真的就很暴力了。
第一步,拨一下。不管会怎么样,都得拨一下吧。这一下有八种可能了吧。
第二步,匹配。拨一下,对所有结果都进行一次的匹配。如果对上了,就返回结果;如果对不上,返回第一步再循环。
注意点一:如果碰到死亡密码,跳过。
注意点二:不要走回头路。
注意点三:空间能省着用就省着用。
好,关键的一步来了,怎么将这个暴力算法往图论算法的方向去引呢。
再看一下上面这个暴力算法,不难看出来,这就是一个节点下面拖八个子节点的八叉树,又是求最短距离,BFS。
int openLock(String[] deadends,String target){//纪录需要跳过的死亡密码Set<String> deads = new HashSet<>();for(String s:deadends) dead.add(s);//纪录已经穷举过的密码set<String> visited = new HashSet<>();Queue<String> q = new LinkedList<>();//从起点开始启动广度优先搜索int step = 0;q.offer("0000");visited.add("0000");while(!q.isEmpty){int sz = q.size();for(int i = 0;i<sz;i++){string cur = q.poll();//判断密码是否合法if(deads.contains(cur)continue;if(cur.equals(target))return step;}//将一个节点的未遍历相邻节点加入队列for(int j=0;j<4;j++){String up = plusOne(cur,j);if(!visited.contains(up){q.offer(up);visited.add(up);}String down = minusOne(cur,j);if(!visited.contains(down){q.offer(down);visited.add(down);}}step++;}return -1;
}
上翻下翻的代码:
String plusOne(String s,int j){char[] ch = s.toCharArray();if(ch[j] == '9')ch[j] = '0';elsech[j] += 1;return new String(ch);
}
String downOne(String s,int j){char[] ch = s.toCharArray();if(ch[j] == '0')ch[j] = '9';elsech[j] -= 1;return new String(ch);
}
一波优化:双向BFS
上面的操作,简化一下是这样的:
从顶部蓝色的节点,找底部红色的节点。
所有节点都被遍历了。
这时候我们换个思路,既然终点也是已知的,那就:
上下同步进行,在中间黑色节点的地方汇聚了。
【C++】算法集锦(5):BFS算法相关推荐
- 自动寻路算法C语言,bfs算法(c语言贪吃蛇自动寻路算法)
广度优先法(BFS)算法C/C++代码,要说明和图解!谢谢! #include #define MAX 10 int front=-1,rear=-1; struct node { int value ...
- 【算法】广度遍历算法的应用 求出距离顶点v0的最短路径长度为最长的一个顶点,图结构的bfs生成树及其双亲表示形式
例: 求出距离顶点v0的最短路径长度为最长的一个顶点,并要求尽可能节省时间 分析: 用bfs算法(利用bfs算法的层次特性): 从v0出发进行广度遍历时, 最后一层的顶点距离v0的最短路径长度最长.因 ...
- 图像保边滤波算法集锦系列
在美颜算法的实现中,如何既能把人脸皮肤磨得光滑,雀斑磨得干净,又能保留五官的自然清晰,这就需要一种能保留边缘信息的平滑滤波器,这种滤波器的好坏在一定程度上,也就影响了美颜磨皮效果的好坏,对此,本人将在 ...
- A*算法(一)算法导言
A*算法(一)算法导言 1. 问题场景 2. 结点图 3. 其他搜索算法 3.1 Dijkstra算法 3.2 BFS算法 3.3 存在障碍的情况 3.4 取长补短 4. A*算法 1. 问题场景 已 ...
- 遍历所有点的最短路径python_图遍历算法之最短路径Dijkstra算法
一.最短路径问题(shortest path problem) 最短路径问题是图论研究中一个经典算法问题,旨在寻找图中两节点或单个节点到其他节点之间的最短路径.根据问题的不同,算法的具体形式包括: 确 ...
- 广度优先搜索 BFS算法
广度优先搜索算法(Breadth-First-Search,BFS),又称作宽度优先搜索.BFS算法是从根节点开始,沿着树的宽度遍历树的节点.如果所有节点均被访问,则算法中止. 算法思想 1.首先将根 ...
- matlab 算法集锦
算法集锦 决策树-划分点 function [n,h]=huafendian1(x) %n返回增益 %h返回划分点 %假设0代表第一类 %假设1代表第二类 %输入x第一列为属性,第二列为用于学习的分类 ...
- 数据结构常见算法集锦
数据结构经典算法集锦 第2章 线性表 KMP算法 //获得next数组 void GetNext(char *t, int next[MAX]) {int i = 1, j = 0;next[1] = ...
- 数据结构经典算法集锦
数据结构经典算法集锦 第2章 线性表 KMP算法 //获得next数组 void GetNext(char *t, int next[MAX]) {int i = 1, j = 0;next[1] = ...
- STL经典算法集锦之排列(next_permutation/prev_permutation
STL经典算法集锦之排列(next_permutation/prev_permutation) 来自:CSDN博客推荐文章 | 时间:2012-05-07 14:54:09 原文链接: http:// ...
最新文章
- 很多人都在埋怨没有遇到好的团队,但好的团队不可能凭空出现,一流的团队不能仅靠团队成员努力,作为Leader,要有可行的规划,并坚定地执行、时势地调整(转)...
- Web APi之控制器选择Action方法过程(九)
- 【错误记录】Kotlin 1.5.0 编译报错 ( 1.5.0 中 Float 不能直接转 Byte 类型 )
- mysql 查看编码方式_Mysql查看编码方式专题
- Kibana_X-Pack管理Elasticsearch权限
- java+selenium报异常org.openqa.selenium.StaleElementReferenceException的解决方案
- caffe 使用小技巧
- 求助各位大神JSP报错急急急!!!!感激不尽
- Codecademy-中文JavaScript系列教程-初认JS
- Canvas-lms 开源在线学习管理系统源码部署(生产版)
- android 日志打印内容完全相同,Log的chatty机制,identical 391 lines
- MyBatis高频面试题
- CSTC 2001 聪明的学生 BZOJ 2523 递归(类搜索,推理)
- LeetCode994 Rotting Oranges解题方案
- vc60.pdb打不开怎么办
- 写文三年了,给大家说点儿心里话
- 金色耶路撒冷 感受圣城之圣
- sql语句中的or用法(及与and和in区别)
- LeetCode 526. 优美的排列
- 物联网通信协议(接入协议)
热门文章
- 按键云数据仓库平台 ,连接按键精灵和云端数据库,可自行配置用做网络验证或云端配置
- 地区三级联动数据库(中国行政区划分数据库)【2018年1月】
- pano2vr.exe下载
- 小葫芦弹幕助手连接服务器失败,为什么自动弹幕发送老是失败?如何解决?
- 移动前端开发和 Web 前端开发的区别是什么
- Revit API: Material 材质
- dtu连接mysql_数据中心使用dtu远程连接oracel 9i数据库问题
- 测试进阶必备,这5款http接口自动化测试工具不要太香~
- 23 - OAI NSA gNB搭建 - 博一
- 回文数c语言(来源:力扣(LeetCode))