一题学会BFS和DFS,手撕不再怕

先复习一下什么是BFS和DFS,各位读者接着往下看就行 

BFS算法

BFS类似于树的层次遍历过程,从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。
舍去空间换时间。

算法思路
队列(先进先出)

1、创建一个空队列queue(用来存放节点)和一个空列表visit(用来存放已访问的节点)

2、依次将起始点及邻接点加入queue和visit中

3、pop出队列中最先进入的节点,从图中获取该节点的邻接点

4、如果邻接点不在visit中,则将该邻接点加入queue和visit中

5、输出pop出的节点

6、重复3、4、5,直至队列为空

DFS算法

DFS沿着树的深度遍历树的节点,
选一条路一直走到底,回溯,遍历所有的子节点,进而达到全局搜索的目的。

算法思路
栈(先进后出)

和BFS相似,只是稍微做了一丝改变

1、创建一个空栈stack(用来存放节点)和一个空列表visit(用来存放已访问的节点)

2、依次将起始点及邻接点加入stack和visit中

3、poo出栈中最后进入的节点,从图中获取该节点的邻接点

4、如果邻接点不在visit中,则将该邻接点加入stack和visit中

5、输出pop出的节点

6、重复3、4、5,直至栈为空

接下来以LeetCode的一道经典题为背景来强化一下写法。

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

输入:grid = [["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]
]
输出:1输入:grid = [ 
["1","1","0","0","0"], 
["1","1","0","0","0"], 
["0","0","1","0","0"],["0","0","0","1","1"] 
] 
输出:3

题目很经典的BFS和DFS都能做,遍历就行

DFS题解

        我们可以将二维网格看成一个无向图,竖直或水平相邻的 1 之间有边相连。为了求出岛屿的数量,我们可以扫描整个二维网格。如果一个位置为 1,则以其为起始节点开始进行深度优先搜索。在深度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。最终岛屿的数量就是我们进行深度优先搜索的次数。

代码:

class Solution {
public:// 深度优先搜索函数,用于将当前岛屿中所有相连的陆地标记为已访问('0')void dfs(vector<vector<char>>& grid, int i, int j) {int n = grid.size(); // 获取网格的行数int m = grid[0].size(); // 获取网格的列数grid[i][j] = '0'; // 将当前位置标记为已访问// 检查当前位置的上、下、左、右四个方向是否有相邻的陆地,如果有,则继续深度优先搜索if (i - 1 >= 0 && grid[i - 1][j] == '1') dfs(grid, i - 1, j); // 上if (i + 1 < n && grid[i + 1][j] == '1') dfs(grid, i + 1, j); // 下if (j - 1 >= 0 && grid[i][j - 1] == '1') dfs(grid, i, j - 1); // 左if (j + 1 < m && grid[i][j + 1] == '1') dfs(grid, i, j + 1); // 右}// 主函数,用于计算网格中岛屿的数量int numIslands(vector<vector<char>>& grid) {int n = grid.size(); // 获取网格的行数if (!n) return 0; // 如果网格为空,则返回岛屿数量为0int m = grid[0].size(); // 获取网格的列数int res = 0; // 用于记录岛屿的数量// 遍历整个网格for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 如果当前位置是陆地('1'),则进入深度优先搜索,将与之相连的所有陆地标记为已访问,并将岛屿数量加一if (grid[i][j] == '1') {res++; // 岛屿数量加一dfs(grid, i, j); // 深度优先搜索,将与当前陆地相连的所有陆地标记为已访问}}}return res; // 返回岛屿的数量}
};

BFS题解

        同样地,我们也可以使用广度优先搜索代替深度优先搜索。为了求出岛屿的数量,我们可以扫描整个二维网格。如果一个位置为 1,则将其加入队列,开始进行广度优先搜索。在广度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。直到队列为空,搜索结束。最终岛屿的数量就是我们进行广度优先搜索的次数 

代码:

class Solution {
public:// 计算岛屿数量的函数int numIslands(vector<vector<char>>& grid) {int n = grid.size(); // 获取网格的行数if (!n) return 0; // 如果网格为空,则返回岛屿数量为0int m = grid[0].size(); // 获取网格的列数int res = 0; // 用于记录岛屿的数量// 遍历整个网格for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 如果当前位置是陆地('1'),则进入广度优先搜索,将与之相连的所有陆地标记为已访问,并将岛屿数量加一if (grid[i][j] == '1') {res++; // 岛屿数量加一grid[i][j] = '0'; // 将当前位置标记为已访问queue<pair<int,int>> neighbors; // 创建一个队列用于存储当前岛屿相邻的陆地neighbors.push({i, j}); // 将当前位置加入队列while (!neighbors.empty()) { // 循环直到队列为空auto t = neighbors.front(); // 取出队首元素neighbors.pop(); // 弹出队首元素int row = t.first, col = t.second; // 获取当前位置的行和列// 检查当前位置的上、下、左、右四个方向是否有相邻的陆地,如果有,则将其加入队列,并标记为已访问if (row + 1 < n && grid[row + 1][col] == '1') {neighbors.push({row + 1, col});grid[row + 1][col] = '0';}if (row - 1 >= 0 && grid[row - 1][col] == '1') {neighbors.push({row - 1, col});grid[row - 1][col] = '0';}if (col + 1 < m && grid[row][col + 1] == '1') {neighbors.push({row, col + 1});grid[row][col + 1] = '0';}if (col - 1 >= 0 && grid[row][col - 1] == '1') {neighbors.push({row, col - 1});grid[row][col - 1] = '0';}}}}}return res; // 返回岛屿的数量}
};

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

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

相关文章

Spring boot 发送文本邮件 和 html模板邮件

Spring boot 发送文本邮件 和 html模板邮件 提示&#xff1a;这里使用 spring-boot-starter-mail 发送文本邮件 和 html模板邮件 文章目录 Spring boot 发送文本邮件 和 html模板邮件一、开启QQ邮箱里的POP3/SMTP服务①&#xff1a;开启步骤 二、简单配置①&#xff1a;引入依赖…

【单例模式】—— C++设计模式【附百度Apollo单例模式详细解读】

参考资料&#xff1a; &#xff08;1&#xff09;单例模式—— 代码随想录 &#xff08;2&#xff09;我给面试官讲解了单例模式后&#xff0c;他对我竖起了大拇指&#xff01; &#xff08;3&#xff09;C 单例模式详解 &#xff08;4&#xff09;单例模式之C实现&#xff0c;…

【Python时序预测系列】基于时域卷积网络TCN实现单变量时间序列预测(源码)

这是我的第248篇原创文章。 一、引言 TCN&#xff08;Temporal Convolutional Networks&#xff09;是一种用于时间序列数据建模的深度学习架构。与传统的循环神经网络&#xff08;RNN&#xff09;和长短期记忆网络&#xff08;LSTM&#xff09;不同&#xff0c;TCN利用卷积操…

java特殊文件——properties属性文件概述

前言&#xff1a; 整理下学习笔记&#xff0c;打好基础&#xff0c;daydayup!! properties properties是一个Map集合&#xff08;键值对合集&#xff09;&#xff0c;但是一般不当作合集。而是用来代表属性文件&#xff0c;通过Properties读写属性文件里的内容 Properties调用方…

MySQL为什么会选错索引

在平时不知道一有没有遇到过这种情况&#xff0c;我明明创建了索引&#xff0c;但是MySQL为何不用索引呢&#xff1f;为何要进行全索引扫描呢&#xff1f; 一、对索引进行函数操作 假设现在维护了一个交易系统&#xff0c;其中交易记录表 tradelog 包含交易流水号(tradeid)、交…

[STM32] Keil 创建 HAL 库的工程模板

Keil 创建 HAL 库的工程模板 跟着100ASK_STM32F103_MINI用户手册V1.1.pdf的第7章步骤进行Keil工程的创建。 文章目录 1 创建相关文件夹2 创建“main.c/h”和“stm32f1xx_clk.c/h”3 复制CMSIS和HAL库4 创建新的Keil工程5 添加组文件夹和工程文件6 配置Keil设置 1 创建相关文件…

[激光原理与应用-77]:基于激光器加工板卡的二次开发软件的系统软硬件架构

目录 一、1个板卡、1个激光器、1个振镜的应用架构、1个工位 &#xff08;1&#xff09;PLC &#xff08;2&#xff09;MES &#xff08;3&#xff09;加工板卡 &#xff08;4&#xff09;激光加工板卡与激光器之间的转接卡 &#xff08;5&#xff09;DB25、DB15 &#x…

基于51单片机的厨房一氧化碳温湿度烟雾粉尘监测报警Proteus仿真

地址&#xff1a;https://pan.baidu.com/s/19tp61m5fOORP47RNh8TWGA 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectroni…

桶排序:原理、实现与应用

桶排序&#xff1a;原理、实现与应用 一、桶排序的基本原理二、桶排序的实现步骤三、桶排序的伪代码实现四、桶排序的C语言实现示例 在日常生活和工作中&#xff0c;排序是一个经常遇到的需求。无论是对一堆杂乱的文件进行整理&#xff0c;还是对一系列数据进行统计分析&#x…

基于深度学习的心律异常分类算法

基于深度学习的心律异常分类系统——算法设计 第一章 研究背景算法流程本文研究内容 第二章 心电信号分类理论基础心电信号产生机理MIT-BIH 心律失常数据库 第三章 心电信号预处理心电信号噪声来源与特点基线漂移工频干扰肌电干扰 心电信号读取与加噪基于小波阈值去噪技术的应用…

Wi-Fi 标准的演进

在数字时代的今天&#xff0c;Wi-Fi已经成为了我们生活中不可或缺的一部分&#xff0c;但这一无线通信技术的演进却是一个精彩而丰富的历程。从最初迈出的第一步&#xff0c;到如今的Wi-Fi 7高速数据传输&#xff0c;每一个Wi-Fi标准的诞生都伴随着无数创新和技术的突破。 802.…

《科学技术创新》是什么级别的期刊?是正规期刊吗?能评职称吗?

问题解答&#xff1a; 问&#xff1a;《科学技术创新》期刊是哪个级别&#xff1f; 答&#xff1a;省级 主管单位&#xff1a;黑龙江省科学技术协会 主办单位&#xff1a;黑龙江省科普事业中心 问&#xff1a;《科学技术创新》期刊影响因子&#xff1f; 答&#xff1a;(2…