单源广度优先搜索 (leetcode经典例题 C++实现)

news/2024/5/4 15:06:46/文章来源:https://blog.csdn.net/jj6666djdbbd/article/details/128056627

文章目录

  • 01矩阵
  • 地图分析
  • 腐烂的橘子

深度优先搜索与广度优先搜索前情回顾:
深度搜索dfs与广度搜索bfs算法总结(c++ 例题)

本节是广度优先搜索的进阶:

01矩阵

传送门:
https://leetcode.cn/problems/01-matrix/?envType=study-plan&id=suan-fa-ru-men&plan=algorithms&plan_progress=1ophias

寻找数组中的每一个元素距离最近的零的距离。

利用广度优先搜索:

  1. 设计一个临时的数组记录状态,我们标记每一个零。
  2. 利用广度搜索把每一个零所在的坐标放入队列中,遍历队列中的每一个元素,以及其上下左右四个方向,并且依次由上一个位置的值得到当前位置的值。

我们要记录数组的每一元素距离最近的零的距离,可以发现:
0距离最近的元素就是零。
1距离最近的零可以由四周的零走一步得到,因此距离是2。

  • 我们可以利用一个标记数组将初始数组中所有的0标记为1,表示我们不需要修改它的值,0的距离就是0.
  • 标记数组默认初始化为0,因此所有非零元素在标记数组都被标记为0
  • 广度优先搜索遍历每一个位置,寻找标记数组中值为0的位置,这即是我们所需要修改的位置,我们可以通过它的上一步 +1 并且把这个值放到一个结果数组中,结果数组中的存储的元素即是最后的答案。
    在这里插入图片描述
class Solution {
private:const int dirX[4]{0,0,-1,1};const int dirY[4]{-1,1,0,0};
public:vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {int nr=mat.size(),nc=mat[0].size();//1. 标记数组vector<vector<int>> fg_mat(nr,vector<int>(nc));//2. 结果数组vector<vector<int>> dst(nr,vector<int>(nc));//3. 队列:广度优先搜索queue<pair<int,int>> q;//4. 预处理: 把所有的0标记为1,代表不需要管0元素的位置,但是我们要从这里开始进行广度优先搜索for (int i=0;i<nr;i++){for (int j=0;j<nc;j++){if (mat[i][j]==0){q.emplace(i,j);fg_mat[i][j]=1;}}}//5. 开始广度搜索while (!q.empty()){pair<int,int> p=q.front();q.pop();//6. 遍历某个点的四个方向for (int i=0;i<4;i++){int mx=p.first+dirX[i];int my=p.second+dirY[i];//7. 只需要计算非零的元素的位置if (mx>=0 && mx<nr && my>=0 && my<nc && fg_mat[mx][my]==0){//8. 位置更新,由上一个的值 +1得到,走了一步dst[mx][my]=dst[p.first][p.second]+1;q.emplace(mx,my);//9. 标记这个点已经走过了fg_mat[mx][my]=1;}}}return dst;}
};

地图分析

传送门:
https://leetcode.cn/problems/as-far-from-land-as-possible/

地图上:0代表海洋,1代表陆地。找到海洋距离陆地最大的距离。 地图中只包含0和1两种。

这道题和上一道题基本类似:

我们寻找距离陆地最大的海洋的坐标位置,可以看作上一题:就是求距离0的最远的距离

上一题我们已经找到了每个点距离最近的0的距离,我们只需要找到这个值最大的点,即是距离最大的点,这道题的答案。
在这里插入图片描述

class Solution {
private:const int dirX[4]{0,0,-1,1};const int dirY[4]{-1,1,0,0};
public:int maxDistance(vector<vector<int>>& grid) {int nr=grid.size(),nc=grid[0].size();//1. 标记数组vector<vector<int>> fg_map(nr,vector<int>(nc));//2. 结果数组vector<vector<int>> dst(nr,vector<int>(nc));//3. 队列queue<pair<int,int>> q;//4. 忽略陆地:把陆地视作上一题的0,我们不考虑他们,把他们标记为1,但是要从他们开始进行广度优先搜索for (int i=0;i<nr;i++){for (int j=0;j<nc;j++){if (grid[i][j]==1){fg_map[i][j]=1;	//注意这个位置q.emplace(i,j);}}}// Step: 如果队列为空或者包含全部的数组的元素,则表示全部是海洋或者陆地,返回-1// (1) q.size()==0  全都是0,即全部都是海洋// (2) q.size()==nr*nc 全部都是1,即全部都是陆地(刚才把陆地的值入队)if (q.size()==0 || q.size()==nr*nc){//全都是海洋:0 陆地:1(队列等于总大小) return -1;}//5. 队列不为空:遍历所有海洋while (!q.empty()){pair<int,int> p=q.front();q.pop();for (int i=0;i<4;i++){int mx=p.first+dirX[i];int my=p.second+dirY[i];//6. 遍历每一方向,广度搜索海洋距离陆地的最大距离if (mx>=0 && mx<nr && my>=0 && my<nc && fg_map[mx][my]==0){//7. 更新结果数组: 由上一步 +1得到这个点的值(即是距离)dst[mx][my]=dst[p.first][p.second]+1;q.emplace(mx,my);//8. 标记为已经走过fg_map[mx][my]=1;}   }}//9. 找到dst结果的最大值,因为我们要找到海洋距离陆地的最大距离int maxnum=0;for (auto& x:dst){for (auto& y:x){maxnum=max(y,maxnum);}}return maxnum;}
};

腐烂的橘子

传送门:
https://leetcode.cn/problems/rotting-oranges/

题目:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
腐烂的距离每一分钟周围的四周都会腐烂,请问当所有的橘子都腐烂,一共需要多长时间,也可能会有不会腐烂的橘子,则返回-1.

我们需要:

  1. 标记数组:记录橘子的状态: 2腐烂,1正常, 0没有橘子
  2. 时间数组:记录时间状态: 0零分钟 1一分钟 … -1表示如果此位置有橘子,则为正常橘子,或者它无橘子,为空。

  1. 首先,标记数组将所有的腐烂的橘子标记为2,时间数组记录时间,如图一,这是第零分钟。
  2. 第一分钟红色为此时扩散的腐烂的橘子,表示数组更新为2(腐烂标记),时间数组更新为 1,表示第一分钟。
  3. 第二分钟蓝色为此时扩散的腐烂的橘子,表示数组更新为2,时间数组更新为 2,表示第二分钟。
  4. 第三分钟绿色为此时扩散的腐烂的橘子,表示数组更新为2,时间数组更新为 3,表示第三分钟。
  5. 第四分钟棕色为此时扩散的腐烂的橘子,表示数组更新为2,时间数组更新为 4,表示第四分钟。
  6. 此时:根据标记数组可知,所有的橘子都被腐烂了,即数组中无 1 出现,此时时间数组对应的 最大值即是最后的时间在这里插入图片描述
    没有腐烂的情况:
  • 标记数组中出现1正常的橘子,而且队列为空,无法继续。
  • 时间数组中出现 1是空或者是正常的橘子,需要对应标记数组来判断是那种情况。当然也可以直接在时间数组中再给空橘子单独设置一个值。
    在这里插入图片描述
class Solution {
private:const int dirX[4]{0,0,-1,1};const int dirY[4]{-1,1,0,0};
public:int orangesRotting(vector<vector<int>>& grid) {int nr=grid.size(),nc=grid[0].size();vector<vector<int>> fg(nr,vector<int>(nc));vector<vector<int>> time(nr,vector<int>(nc));queue<pair<int,int>> q;for (int i=0;i<nr;i++){for (int j=0;j<nc;j++){//腐烂橘子if (grid[i][j]==2){q.emplace(i,j);fg[i][j]=2;     //腐烂橘子 表示为2time[i][j]=0;   //时间数组 表示为0}if (grid[i][j]==1){fg[i][j]=1;     //正常橘子 表示为1time[i][j]=-1;  //时间数组 表示为-1}}}while (!q.empty()){pair<int,int> p=q.front();q.pop();for (int i=0;i<4;i++){int mx=p.first+dirX[i];int my=p.second+dirY[i];if (mx>=0 && mx<nr && my>=0 && my<nc && fg[mx][my]==1){fg[mx][my]=2;   //橘子变腐烂time[mx][my]=time[p.first][p.second]+1;  //时间增加q.emplace(mx,my);  //从下一个腐烂的橘子开始}}}int max_num=0;for (int i=0;i<nr;i++){for (int j=0;j<nc;j++){max_num=max(max_num,time[i][j]);//时间是-1,并且表示为1,则这个橘子未腐烂,返回-1if (time[i][j]==-1 && fg[i][j]==1){return -1;}}}return max_num;}
};

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

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

相关文章

如何Cisco的学员 摆脱游客登录

Cisco Packet Tracer 是一款强大的网络模拟工具&#xff0c;可用于在虚拟实验环境中练习网络、物联网和网络安全技能。您不需要任何硬件&#xff0c;即可获得实操经验&#xff01; 相信很多小伙伴在使用cisco packet tracer这个思科数据包跟踪器 - 网络仿真工具时在登录的时候…

XML的创建和读取

rapidxml是一个快速的xml库&#xff0c;由C模板实现的高效率xml解析库&#xff0c;同时也是boost库的property_tree的内置解析库。 当使用rapidxml时&#xff0c;只需要把rapidxml.hpp 、 rapidxml_print.hpp 和 rapidxml_utils.hpp 三个文件拷贝到你的工程目录下&#xff0c;就…

Redis持久化策略AOF、RDB详解及源码分析

写在前面 以下内容是基于Redis 6.2.6 版本整理总结 一、Redis为什么要持久化 Redis 是一个内存数据库&#xff0c;就是将数据库中的内容保存在内存中&#xff0c;这与传统的MySQL&#xff0c;Oracle等关系型数据库直接将内容保存到硬盘中相比&#xff0c;内存数据库的读写效…

Gof23-创建型-工厂-单例-抽象工厂-建造-原型以及UML的绘制

创建型的设计模式工厂模式单例模式抽象工厂建造者模式原型模式UML图形的绘制工厂模式 工厂模式 Factory Pattern 适用的场景&#xff1a;统一的接口作为统一的零件&#xff0c;实现类作为零件的组合&#xff0c;将实例产品类的生产交给工厂&#xff0c;用户只需要面对工程提取…

Java_接口

目录 1.接口的语法规则 2.接口使用 3.接口特性 4.实现多个接口 1&#xff09;下面通过类来表示一组动物&#xff1b; 2&#xff09;另外再提供一组接口, 分别表示 "会跑的", "会飞的", "会游泳的"&#xff1b; 3&#xff09;接下来我们创建…

十九种卷积

参考文章:一文看尽深度学习中的20种卷积(附源码整理和论文解读) - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/381839221 一、原始卷积(Vanilla Convolution) CNNs中的卷积,也称为滤波器,是由一组具有固定窗口大小且带可学习参数(learnable paramerters)的卷积核所组…

Unity 如何实现框选游戏战斗单位

文章目录&#x1f354; Preface✨ 如何在屏幕坐标系内绘制框选框&#x1f389; 根据框选范围定位其在世界坐标系中对应的区域&#x1f947; 在该区域内进行物理检测&#x1f354; Preface 本文简单介绍如何实现即时战略游戏中框选战斗单位的功能&#xff0c;如图所示&#xff…

【外卖项目实战开发二】

文章目录1、完善登录功能问题分析代码实现2、新增员工需求分析数据模型代码开发3、员工信息分页查询需求分析代码开发4、启用/禁用员工账号需求分析代码开发代码修复5、编辑员工信息需求分析代码开发1、完善登录功能 问题分析 前面我们已经完成了后台系统的员工登录功能开发&…

基于JavaWeb的婚恋交友网站设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

大数据:HDFS的Shell常用命令操作

文章目录一 HDFS的Shell介绍二 HDFS常用命令操作01 创建目录&#xff08;1&#xff09;创建单层目录&#xff08;3&#xff09;创建多层目录02 查看目录03 上传本地文件到HDFS04 查看文件内容05 下载HDFS文件到本地06 删除HDFS文件07 删除HDFS目录08 移动目录或文件09 文件合并…

第九章 堆排序与TOPK问题

第九章&#xff1a;堆排序与TOPK问题一、堆排序&#xff1a;1、思路分析&#xff1a;&#xff08;1&#xff09;建堆&#xff08;2&#xff09;排序2、堆排序模板二、TOPK问题&#xff1a;1、什么是TOPK问题&#xff1f;2、解决方法一、堆排序&#xff1a; 假设我们实现一个小…

26k Star, 理解Git太轻松了。。。

程序员宝藏库&#xff1a;gitee.com/sharetech_lee/CS-Books-Store Git是目前使用比较广泛一款版本控制工具&#xff0c;从事开发工作&#xff0c;很难绕开Git。 因此&#xff0c;关于如何快速学习Git使用一直都是一个经久不衰的话题。 前不久我在另外一篇文章中曾提到Git对初…

树莓派上搭建SVN服务器

目录 一、服务端安装步骤 1.安装svn 2.创建目录 3.创建版本仓库 4.修改配置&#xff08;authz,passwd,svnserve.conf&#xff09; 5.启动服务 二、tortoisSVN客户端安装 三、结束 一、服务端安装步骤 1.安装svn sudo apt-get install subversion 2.创建目录 sudo m…

用Python蹭别人家图片接口,做一个【免费图床】吧

打开本文&#xff0c;相信你确实需要一个免费且稳定的图床&#xff0c;这篇博客就让你实现。 文章目录⛳️ 谁家的图床⛳️ 实战编码⛳️ 第一轮编码⛳️ 第二轮编码⛳️ 第三轮编码⛳️ 第四轮编码⛳️ 谁家的图床 这次咱们用新浪微博来实现【免费图床应用】&#xff0c;通过…

基于keras 卷积神经外网络搭建的手写数字识别 完整代码+数据可直接运行

项目介绍: 适合新手入门学习代码数据很简洁 上结果: 主要的卷积神经网络: 卷积是指在滑动中提取特征的过程,可以形象地理解为用放大镜把每步都放大并且拍下来,再把拍下来的图片拼接成一个新的大图片的过程。 2D卷积是一个相当简单的操作: 我们先从一个小小的权重矩阵…

十个值得珍藏的正则表达式

正则表达式常学常忘&#xff0c;记规则不如记例子&#xff0c;记多不如记精&#xff0c;记例子就记最经典的。下面是本人珍藏的十个有用的正则表达式&#xff0c;不吝分享&#xff0c;以飨读者。 正则表达式要点 小括号&#xff1a;代表分组 中括号&#xff1a;代表集合 大括号…

外卖项目08---Linux

目录 一、 Linux简介 119 二、Linux安装 120 三、常用命令 122 3.1Linux命令初体验 3.1.1 command [-options] [parameter] 3.2Linux常用命令---文件目录操作命令-ls&-cd&-cat 124 3.2.1list 3.2.2 cd 3.2.3 cat 3.3 Linux常用命令---文件目录操作命令…

机器学习模型与backtrader框架整合

原创文章第116篇&#xff0c;专注“个人成长与财富自由、世界运作的逻辑&#xff0c; AI量化投资”。 北京疫情似乎还没有到拐点&#xff0c;但这三天结束后应该会到来。 今天重点说说&#xff0c;机器学习模型整合到我们的回测框架中&#xff0c;并与backtrader连接起来回测…

傻白入门芯片设计,先进封装技术(五)

集成电路芯片与封装之间是不可分割的整体。没有一个芯片可以不用封装就能正常工作&#xff0c;封装对芯片来说是必不可少的&#xff0c;随着IC生产技术的进步&#xff0c;封装技术也不断更新换代&#xff0c;每一代IC都与新一代的IC封装技术紧密相连。 目录 一、什么是封装&am…

详解设计模式:抽象工厂模式

工厂方法模式&#xff0c;又称工厂模式、多态工厂模式和虚拟构造器模式&#xff0c;通过工厂父类定义负责创建产品的公共接口&#xff0c;子类负责生产具体对象。可以理解为简单工程模式的升级&#xff0c;解决简单工厂模式的弊端。 &#xff5e; 本篇内容包括&#xff1a;关于…