文章目录

  • 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;}
};

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

  1. 【广度优先搜索】leetcode 994. 腐烂的橘子

    994. 腐烂的橘子 文章目录 题目描述 示例1: 示例2: 示例3: 提示 方法:多源广度优先搜索 解题思路 代码 复杂度分析 题目描述 在给定的 m x n 网格 grid 中,每个单元格可以有以 ...

  2. Leetcode广度优先搜索笔记2 腐烂的橘子

    994. 腐烂的橘子:带有变量控制的矩阵中的广度优先搜索 在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一: 值 0 代表空单元格: 值 1 代表新鲜橘子: 值 2 代表腐烂的 ...

  3. 力扣入门级广度优先搜索/遍历刷题小结

    刷这些题时死掉的脑细胞是我当年在<线性代数>和<概率论与数理统计>课上没学明白时苟活下来的( 这几题基本是抄作业了,但我发现官方题解写的也很绕,都不知道是我天然看到这类题就头晕 ...

  4. 深度优先搜索与广度优先搜索区别和案例

    今天周末,心血来潮打开LeetCode做一道题: https://leetcode-cn.com/problems/number-of-enclaves/ 看到题,我的第一想法是: 从边缘的陆地开始, ...

  5. 单源最短路径Dijkstra算法的思想、详细步骤、代码

    目录 一.算法思想 二.算法详细步骤 三.伪代码 + C++代码 四.算法复杂度分析 五.算法改进 六.应用案例 一.算法思想 1.Dijkstra 算法是用来求解单源最短路径问题的经典算法,其本质上 ...

  6. 二叉树层序遍历(广度优先搜索)基础概念与经典题目(Leetcode题解-Python语言)

    二叉树的广度优先搜索即从上到下.从左到右地进行搜索,对于层序遍历(Level Order)问题,即依次遍历第一层节点.第二层节点-等,基本可以秒杀. 广度优先搜索是通过队列来实现的,python中优先 ...

  7. 广度优先搜索BFS进阶(一):多源BFS、优先队列BFS、双端队列BFS

    一.多源BFS 在上一篇博客:广度优先搜索BFS基础中,我们接触到的BFS均是单起点(单源)的,但是对于某一些问题,其有多个起点,此类问题我们称为多源BFS问题.先思考下面一道例题: 1.腐烂的橘子 ...

  8. 广度优先搜索——岛屿数量(Leetcode 200)

    题目选自Leetcode 200. 岛屿数量 经典的搜索题,求岛屿数量 这里我用的是广度优先搜索BFS 最朴素的方法, 虽然效率不高,但是简单易懂 主要的问题在于:如何确定有多少个岛屿? 每次对一个& ...

  9. 【2023王道数据结构】【图】通过C++实现图的BFS(广度优先遍历)算法求单源最短路径问题C、C++完整实现(可直接运行)

    ~~~笔锋至此又怎能平淡而终,故事开始便不承认普通✌✌✌ ✌ 题目及题解持续更新中 [2023王道数据结构目录]课后算法设计题C.C++代码实现完整版大全 题目: 通过C++实现图的BFS(广度优先遍 ...

最新文章

  1. 设计模式之桥接模式(Bridge)摘录
  2. 【leetcode】 算法题1 两数之和
  3. php 如何启动ica文件,IE11打开ICA文件时无法直接调用Citrix Receiver?
  4. 微软修复Windows 10周年更新KB3194496累积更新安装问题
  5. Softmax vs. SoftmaxWithLoss 推导过程
  6. 怎么用cmd关闭系统弹窗_C盘空间越来越小怎么办?5招帮你解决问题!
  7. [翻译 EF Core in Action 2.1] 设置一个图书销售网站的场景
  8. 每日两SQL(2),欢迎交流~
  9. 阐述html语言的理解,大学语文课后思考题答案
  10. 三层架构 android访问MSSQL数据库 程序 (服务器端)
  11. java 日本时区_java时区时间ZoneOffset, ZoneId,OffsetTime,OffsetDateTi
  12. 莫陷入点击和评论陷阱
  13. ArcPad8新功能介绍
  14. 永别了,91网站!宣布永久关闭
  15. thinkpadt410接口介绍_联想t410配置参数详解
  16. 国家图书馆认证中国长峰制定的《婴幼儿血管瘤临床路径》
  17. 26、backtrader的一些基本概念-市价止损单(stop_order)与限价止损单(stop limit order)的创建和撮合逻辑
  18. 基于STM32蓝牙无线手环脉搏心率计步器体温监测设计
  19. 2021 csp-s
  20. 知乎上40个有趣回复,很精辟!

热门文章

  1. 基于Web的小型购书网站
  2. 没有javaeye积分了,谁了解浙大网新恒天公司啊?
  3. pythonnet的使用
  4. SQL触发器--当表数据发生变化时,将数据同步到另一张表中
  5. I/O设备和设备控制器
  6. 【LED 大屏】是如何安装的、带你了解整个过程
  7. 聊天机器人介绍 | 是什么?有什么用?聊天机器人十大排行榜
  8. todo工具、日程管理工具、桌面日程清单app——:日历清单(mac)
  9. 爆款打造,怎样打造爆款,爆款失败的原因分析
  10. 90天掌握高级JS(第一个阶段日志)