BFS(广度优先搜索)——搜索算法

        BFS,也就是广度(宽度)优先搜索,二叉树的层序遍历就是一个BFS的过程。而前、中、后序遍历则是DFS(深度优先搜索)。从字面意思也很好理解,DFS就是一条路走到黑,BFS则是一层一层地展开。

关于二叉树的创建与遍历,大家可以参考下文:

二叉树创建和遍历_二叉树的建立与遍历-CSDN博客

下图分别是DFS和BFS的遍历顺序图解: 

    

一、层序遍历

接下来我们直接来看题,从题中感受BFS的魅力。

        N叉树与二叉树的区别无非就是二叉树最多只有两个子节点用left和right两个指针就够储存。而N叉树有N多个节点,需要一个指针数组来储存

在用BFS解决问题时几乎都要借助队列结构,用队列的先进先出特性来储存上一层的数据。

        首先把根节点放到队列里面,然后从队列里面取节点出来,把节点取出来后,通过它找到它的子节点并带入到队列里面。那么这个节点的使命就算完成了,需要把它踢出队列。循环往复直到最后队列为空,则完成层序遍历。

        但对于这个题并不是简单的层序遍历就行,它还要把每一层划分出来。这个其实也很简单,只要记录每一层有几个节点(记为n个),然后一次性的遍历n个,并把这n个元素用数组储存起来。可以直接使用size()计算该层元素个数。

代码示例:

class Solution {
public:vector<vector<int>> levelOrder(Node* root){if(!root) return {};vector<vector<int>> ret;queue<Node*> qu;qu.push(root);while(!qu.empty()){vector<int> arr;int n=qu.size();//获取该层有一个元素while(n--)//取出该层的所以元素并把子节点带入{Node* rt=qu.front();qu.pop();arr.push_back(rt->val);for(int i=0;i<rt->children.size();i++)qu.push(rt->children[i]);}if(!arr.empty()) ret.push_back(arr);}    return ret;}
};

二、最短路问题

例如我们要找到从起点(1)到终点(8)的最短路径。

最终找到最短路如下: 

例题:

首先因为它是上下左右式的扩散,所以使用一个小技巧:向量坐标

dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};

我们使用

for(int k=0;k<4;k++)

        x1 = x+dx[k], y1 = y+dy[k];

就可以得到(x, y)的上下左右坐标的(x1, y1)。

        它的扩展逻辑就和上文层序遍历中那一题差不多,但需要一个变量记录层数。在扩展过程中需要判断是否是目标值,还需要把扩展到的元素做标记

代码示例:

class Solution {
public:int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};int nearestExit(vector<vector<char>>& maze, vector<int>& entrance){int n = maze.size(),m = maze[0].size();vector<vector<bool>> hash(n,vector<bool>(m));//记录是否已经搜索过queue<pair<int,int>> qu;qu.push({entrance[0],entrance[1]});hash[entrance[0]][entrance[1]] = true;int ret = 0;//记录层数while(!qu.empty()){ret++;int sz = qu.size();while(sz--){auto [a,b] = qu.front();qu.pop();for(int k=0;k<4;k++){int x = a+dx[k],y = b+dy[k];if(x>=0&&x<n&&y>=0&&y<m&&!hash[x][y]&&maze[x][y]=='.'){if(x==0||x==n-1||y==0||y==m-1) return ret;hash[x][y] = true;qu.push({x,y});}}}}return -1;}
};

        这个题我们可以做一个多趟的BFS,首先确定第一个起点和终点,进行BFS搜索并记录路径长度。

        注意:由题可知没有两棵树的高度是相同的,也就是说树的高度和它的坐标是一一对应的

具体操作如下:

        把所有树的高度(>1的元素)都记录到一个数组中,然后对该数组进行排序。这样我们就知道搜索的先后顺序。

        封装一个bfs函数,如pair<int,int> bfs(int x,int y,int target,vector<vector<int>>& forest),传入起点坐标与终点的值,它的作用是记录起点到终点的最短距离,然后返回终点的坐标。如果不能被搜索到返回{-1, -1}。

        距离的计算我们可以使用一个全局变量在bfs中累加。

        进行一次bfs后得到的返回值作为下一次搜索的起点下标,而终点值从刚才排序好的数组中取到。

        最后,使用循环把数组中所有的值都搜索一遍。

class Solution {
public:int ret = 0,m = 0,n = 0;int dx[4] = {0,0,-1,1},dy[4]={-1,1,0,0};int cutOffTree(vector<vector<int>>& forest){m = forest.size(),n = forest[0].size();vector<int> arr;for(int i=0;i<m;i++)for(int j=0;j<n;j++)if(forest[i][j]>1) arr.push_back(forest[i][j]);sort(arr.begin(),arr.end());int x = 0,y = 0;for(int i=0;i<arr.size();i++){if(i==0&&arr[i]==forest[0][0]) continue;auto [a,b] = bfs(x,y,arr[i],forest);if(a==-1) return -1;x = a,y = b;}return ret;}pair<int,int> bfs(int x,int y,int target,vector<vector<int>>& forest){vector<vector<bool>> hash(m,vector<bool>(n));queue<pair<int,int>> qu;qu.push({x,y});hash[x][y] = true;while(!qu.empty()){ret++;int sz = qu.size();while(sz--){auto [a,b] = qu.front();qu.pop();for(int k=0;k<4;k++){int x1 = a+dx[k],y1 = b+dy[k];if(x1>=0&&x1<m&&y1>=0&&y1<n&&!hash[x1][y1]&&forest[x1][y1]!=0){if(forest[x1][y1]==target) return {x1,y1};hash[x1][y1]=true;qu.push({x1,y1});}}}}return {-1,-1};}
};

三、多源最短路问题

多源最短路它的特点就是可以选择多个起点,找出到达终点的最短路径。

        其实它和单源最短路差别并不是很大,我们只需要把所有起点看作一个整体,也就是把它当作“超级源点”那么它就是一个单源最短路问题。

        这个题很明显我们可以使用BFS解决,但是如果每个1的位置都用一次BFS搜索,未免也太麻烦,那么我们可以用多源最短路的思想,把所有0当作起点,然后去搜索1并填充最短路径。                那么为什么不用所有的1为起点去搜索0呢,因为我们需要填写的信息是1的位置,如果用1去搜索0的话,最后就不能找到原来那个1的位置。 

代码示例:

class Solution {
public:int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};vector<vector<int>> updateMatrix(vector<vector<int>>& mat){int m=mat.size(),n=mat[0].size();vector<vector<int>> ret(m,vector<int>(n,-1));//充当了哈希表的功能queue<pair<int,int>> q;for(int i=0;i<m;i++)//把所有起点加入队列中{for(int j=0;j<n;j++){if(mat[i][j]==0){q.push({i,j});ret[i][j]=0;}}}int tmp = 0;while(!q.empty()){tmp++;int sz = q.size();while(sz--){auto [i,j]=q.front();q.pop();for(int k=0;k<4;k++){int x=dx[k]+i,y=dy[k]+j;if(x>=0&&x<m&&y>=0&&y<n&&ret[x][y]==-1){ret[x][y]=tmp;q.push({x,y});}}}}return ret;}
};

四、拓扑排序问题

在一个有向无环图中,要保证在 “被指向的节点” 出现之前,它的 “父节点” 要先出现。

通常用顶点来表示一个活动,用边的指向来表示活动之间的先后顺序。如:

如上,拓扑排序的结果可能有多种,只要合法就行。

排序方法:

  • 1.记录每个顶点的入度边个数,和出度边的指向。
  • 2.把所有入度边为0的节顶点push到队列中。
  • 3.拿出队头元素加入到结果中。
  • 4.把该元素指向的所有顶点入度边减1,并判断如果有顶点的入度边为0则push到队列。
  • 循环执行3,4部直到队列为空,则完成排序。

210. 课程表 II - 力扣(LeetCode)

class Solution {
public:vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {vector<int> in(numCourses), ret;vector<vector<int>> out(numCourses);for(int i=0;i<prerequisites.size();i++){int a=prerequisites[i][0];int b=prerequisites[i][1];in[a]++;out[b].push_back(a);}    queue<int> q;for(int i=0;i<numCourses;i++)if(in[i]==0) q.push(i);while(!q.empty()){int v = q.front();ret.push_back(v);q.pop();for(int i=0;i<out[v].size();i++)if(--in[out[v][i]]==0) q.push(out[v][i]);}if(ret.size()!=numCourses) return {};return ret;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/70017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库 - Sqlserver - SQLEXPRESS、由Windows认证改为SQL Server Express认证进行连接 (sa登录)

本文讲SqlServer Express版本在登录的时候&#xff0c; 如何由Windows认证&#xff0c;修改为Sql Server Express认证。 目录 1&#xff0c;SqlServer Express的Windows认证 2&#xff0c;修改为混合认证 3&#xff0c;启用sa 用户 4&#xff0c;用sa 用户登录 下面是详细…

GWO优化SVM回归预测matlab

灰狼优化算法&#xff08;Grey Wolf Optimizer&#xff0c;简称 GWO&#xff09;&#xff0c;是由澳大利亚格里菲斯大学的 Mirjalii 等人于 2014 年提出的群智能优化算法。该算法的设计灵感源自灰狼群体的捕食行为&#xff0c;核心思想是对灰狼社会的结构与行为模式进行模仿。 …

elasticsearch8.15 高可用集群搭建(含认证Kibana)

文章目录 1.资源配置2.系统参数优化3.JDK17安装4.下载&安装ES 8.155.生成ES的证书(用于ES节点之间进行安全数据传输)6.修改ES 相关配置文件7.创建es用户并启动8.配置ES的账号和密码(用于ES服务端和客户端)9.下载和安装Kibana10.编辑Kibana配置文件11.启动Kiabana12.访问Kia…

地址查询API接口:高效查询地址信息,提升数据处理效率

地址查询各省市区API接口 地址查询是我们日常生活中经常遇到的一个需求&#xff0c;无论是在物流配送、地图导航还是社交网络等应用中&#xff0c;都需要通过地址来获取地理位置信息。为了满足这个需求&#xff0c;我们可以使用地址查询API接口来高效查询地址信息&#xff0c;提…

3、C#基于.net framework的应用开发实战编程 - 实现(三、三) - 编程手把手系列文章...

三、 实现&#xff1b; 三&#xff0e;三、编写应用程序&#xff1b; 此文主要是实现应用的主要编码工作。 1、 分层&#xff1b; 此例子主要分为UI、Helper、DAL等层。UI负责便签的界面显示&#xff1b;Helper主要是链接UI和数据库操作的中间层&#xff1b;DAL为对数据库的操…

vscode软件操作界面UI布局@各个功能区域划分及其名称称呼

文章目录 abstract检查用户界面的主要区域官方文档关于UI的介绍 abstract 检查 Visual Studio Code 用户界面 - Training | Microsoft Learn 本质上&#xff0c;Visual Studio Code 是一个代码编辑器&#xff0c;其用户界面和布局与许多其他代码编辑器相似。 界面左侧是用于访…

类和对象(下)——类型转化 static成员 内部类 匿名对象 拷贝对象优化

一、类型转换 1.1 类型转化特点 C支持内置类型隐式类型转换为类类型对象&#xff0c;需要有相关内置类型为参数的构造函数。构造函数前面加explicit就不再支持隐式类型转换。类类型的对象之间也可以隐式转换&#xff0c;需要相应的构造函数支持 内置类型转换为类类型对象&#…

基于场景图的零样本目标导航

参考论文&#xff1a;SG-Nav&#xff1a;Online 3D Scene Graph Prompting for LLM-based Zero-shot Object Navigation 0 前言 基于现成的视觉基础模型VFMs和大语言模型LLM构建了无需任何训练的零样本物体巡航框架SG-Nav。 通过VLMs将机器人对场景的观测构建为在线的3D场景图…

开屏广告-跳过神器

给大家介绍一款超实用的软件——SKIP&#xff0c;它堪称李跳跳的最佳平替&#xff01;这款软件已经在Github开源免费&#xff0c;完全无需担心内置源问题&#xff0c;也无需导入任何规则。安装完成后&#xff0c;即可直接使用&#xff0c;非常便捷&#xff01; 首次打开软件时…

大模型本地化部署(Ollama + Open-WebUI)

文章目录 环境准备下载Ollama模型下载下载Open-WebUI 本地化部署的Web图形化界面本地模型联网查询安装 Docker安装 SearXNG本地模型联网查询 环境准备 下载Ollama 下载地址&#xff1a;Ollama网址 安装完成后&#xff0c;命令行里执行命令 ollama -v查看是否安装成功。安装成…

自制虚拟机(C/C++)(三、做成标准GUI Windows软件,扩展指令集,直接支持img软盘)

开源地址:VMwork 要使终端不弹出&#xff0c; #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") 还要实现jmp near 0x01类似的 本次的main.cpp #include <graphics.h> #include <conio.h> #include <windows.h> #includ…

【游戏设计原理】97 - 空间感知

一、游戏空间的类型 将游戏设计中的空间设计单独提取出来&#xff0c;可以根据其结构、功能和玩家的交互方式划分为以下几种主要类型。这些类型可以单独存在&#xff0c;也可以组合使用&#xff0c;以创造更加复杂和有趣的游戏体验。 1. 线性空间 定义&#xff1a;空间设计是…

基于开源AI智能名片2 + 1链动模式S2B2C商城小程序视角下的个人IP人设构建研究

摘要&#xff1a;本文深入探讨在开源AI智能名片2 1链动模式S2B2C商城小程序的应用场景下&#xff0c;个人IP人设构建的理论与实践。通过剖析个人IP人设定义中的“诉求”“特质”“可感知”三要素&#xff0c;结合该小程序特点&#xff0c;阐述其对个人IP打造的影响与推动作用&…

数据库和数据表的创建、修改、与删除

1.标识符命名规则 数据库名、表名不得超过30个字符&#xff0c;变量名限制为29个 必须只能包含A-Z,a-z,0-9,_共63个字符 数据库名、表名、字段名等对象名中间不能包含空格 同一个MySQL软件中&#xff0c;数据库不能同名&#xff1b;同一个库中&#xff0c;表不能重名&#…

算法日记10:SC62求和(单调栈)(共享求解)

一、题目 二、题解&#xff1a; 1、首先&#xff0c;我们看到题目的第一个想法&#xff0c;就是把样例答案如何求解给列出来&#xff0c;图例如下 2、通过分析样例&#xff0c;可以很清晰的发现每一个数字都有其管辖的区间&#xff0c;因此我们可以想到能否找到一个数字它所管…

Revit二次开发 自适应族添加放样融合

大多数博客给出的方案都是如何在有自适应族的情况下进行修改定位点或是将数据传入自适应族,如何直接在族文件中创建自适应模型并将点转换为自适应点,连接自适应点成为自适应路径这种方式没有文章介绍. 下面的代码中给出了如何在自适应族文件中创建参照点并转换为自适应点连接…

基于VMware的ubuntu与vscode建立ssh连接

1.首先安装openssh服务 sudo apt update sudo apt install openssh-server -y 2.启动并检查ssh服务状态 到这里可以按q退出 之后输入命令 &#xff1a; ip a 红色挡住的部分就是我们要的地址&#xff0c;这里就不展示了哈 3.配置vscode 打开vscode 搜索并安装&#xff1a;…

解决SetWindowCompositionAttribute使控件文本透明的问题

用以下参数调用该API&#xff0c;能实现类似Aero的模糊透明效果。 参数具体含义见 https://zhuanlan.zhihu.com/p/569258181 http://www.memotech.de/WindowComposition/Text.txt http://www.memotech.de/WindowComposition/WindowComposition.zip DWORD accent[4] { 3,0,0,0 …

使用 DeepSeek-R1 与 AnythingLLM 搭建本地知识库

一、下载地址Download Ollama on macOS 官方网站&#xff1a;Ollama 官方模型库&#xff1a;library 二、模型库搜索 deepseek r1 deepseek-r1:1.5b 私有化部署deepseek&#xff0c;模型库搜索 deepseek r1 运行cmd复制命令&#xff1a;ollama run deepseek-r1:1.5b 私有化…

SQL入门到精通 理论+实战 -- 在 MySQL 中学习SQL语言

目录 一、环境准备 1、MySQL 8.0 和 Navicat 下载安装 2、准备好的表和数据文件&#xff1a; 二、SQL语言简述 1、数据库基础概念 2、什么是SQL 3、SQL的分类 4、SQL通用语法 三、DDL&#xff08;Data Definition Language&#xff09;&#xff1a;数据定义语言 1、操…