【经典算法】BFS_FloodFill算法
目录
- 1, 算法介绍
- 2,算法原理和代码实现(含题目链接)
- 733.图像渲染
- 200.岛屿的数量
- 695.岛屿的最大面积
- 130.被围绕的区域
- 3, 算法总结
1, 算法介绍
FloodFill(洪水灌溉) 算法介绍:
假设一个 4 * 4 的方格代表一块土地,土地上有些地方是凹陷的(假设用负数表示,-1,-2,-3……大小表示凹陷程度),有些地方是凸起的(假设用正数表示,1,2,3,4……大小表示凸起程度)。
此时如果发洪水或是下雨,就会把凹陷的地方填满水,凸起的部分就会把凹陷的部分包围,填满水的区域会被连成一片一片的。
所以这类问题要么是问有多少块填平的区域,要么是问最大的区域面积是多少,要么是问某一块区域的边长是多少。
有些问题是规定只能上下左右联通,有些是斜对角也能联通。
本质就是找出具有相同性质的联通块。
解决方法:
dfs :深度优先遍历(使用递归)
bfs:宽度优先遍历(层序遍历)
2,算法原理和代码实现(含题目链接)
733.图像渲染


算法原理:
使用队列进行层序遍历(bfs)。首先要记录原坐标的像素值,再以这个坐标为中心,上下左右四个方向进行遍历,如果发现有相等的像素值,就把这个坐标入队列并且修改成指定的像素值。接着再取出队头元素,进行判断,修改,遍历四个方向,入队列…直到队列为空,此时就把图中所有等于原像素值的位置修改成了指定的像素值。
细节/技巧问题:
(1) 记录完原坐标的像素值时,先进行一次判断,是否等于要修改的值,如果是,就直接返回图像。
(2) 要得到上下左右四个方向的坐标有技巧。

(3) 要注意遍历四个方向时坐标不能越界。
代码实现:
class Solution
{typedef pair<int, int> PII;int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};
public:vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {int prev = image[sr][sc];if(prev == color) return image; // 处理特殊情况int m = image.size();int n = image[0].size();queue<PII> q;q.push({sr ,sc});while(q.size()){auto [a, b] = q.front();q.pop();if(image[a][b] == prev) image[a][b] = color;// 判断上下左右的值for(int i = 0; i < 4; i++){int x = a + dx[i];int y = b + dy[i];if(x >=0 && x < m && y >=0 && y < n && image[x][y] == prev)q.push({x, y});}}return image;}
};
200.岛屿的数量


算法原理:
这道题就是第一道题的进阶版,也是使用队列层序遍历(bfs),只不过是多次使用bfs算法,所以把它写成一个函数,bfs在这里的作用是标记陆地。遍历整个矩阵,当遇到陆地(‘1’)并且没有被遍历过时,使用bfs并岛屿数量+1。
细节/技巧问题:
(1) 当取出队头坐标进行上下左右遍历时,一定会遍历到相同的位置,此时就要进行区分。可以定义一个bool类型的标记数组vis,如果位置已经遍历过,置为true,否则为false。
(2) 给bfs函数进行传参时,如果想要形参简洁一些,可以把一些变量定义在main函数外变为公有的,这样可以减少麻烦。比如这道题里矩阵的行和列,标记数组vis等
代码实现:
class Solution
{int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};int m,n;bool vis[301][301]; // 记录位置有没有被遍历过,true有,false没有
public:int numIslands(vector<vector<char>>& grid) {m = grid.size(), n = grid[0].size();int ret = 0; //记录岛屿数量// 遍历整个网格for(int i = 0;i < m; i++){for(int j = 0;j < n; j++){// 如果是陆地并且没有遍历过if(grid[i][j] == '1' && !vis[i][j]){// 把这块陆地标记bfs( grid,i, j);ret++;}}} return ret;}void bfs(vector<vector<char>>& grid, int i, int j){queue<pair<int ,int>> q;q.push({i, j});vis[i][j] = true; // 入队列代表你已经遍历过了,要标记while(q.size()){auto [a,b] = q.front();q.pop();for(int k = 0; k < 4; k++){int x = a + dx[k], y = b + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1' && !vis[x][y]){q.push({x,y});vis[x][y] = true;}}}}
};
695.岛屿的最大面积



算法原理:
这道题也是基于前两题的bfs算法,也要多次使用bfs,所以也写成函数。它的作用是标记陆地并且统计每块陆地的面积。遍历矩阵,当遇到没有被遍历过的陆地(1)时,调用bfs函数进行标记与统计,遇到符合要求的坐标并且入队列后,陆地面积+1。统计完每一块陆地的面积再返回给main函数。
细节/技巧问题:
参考前面两题。
代码实现:
class Solution
{int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};bool vis[51][51];int m,n;
public:int maxAreaOfIsland(vector<vector<int>>& grid) {m = grid.size(), n = grid[0].size();int ret_max = 0;int ret = 0;for(int i = 0;i < m; i++){for(int j = 0; j < n; j++){if(grid[i][j] == 1 && !vis[i][j]){ret = bfs(grid, i, j);ret_max = max(ret, ret_max);}}}return ret_max;}int bfs(vector<vector<int>>& grid, int i, int j){int ret = 0; // 记录岛屿面积queue<pair<int ,int>> q;q.push({i, j});vis[i][j] = true; // 记得标记ret++;while(q.size()){auto[a,b] = q.front();q.pop();for(int k = 0; k < 4; k++){int x = a+dx[k], y = b+dy[k];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && !vis[x][y]){q.push({x, y});vis[x][y] = true;ret++;}}}return ret;}
};
130.被围绕的区域



算法原理:
这道题也是bfs算法的综合运用。如果按照题意正面去解决,就是直接把除与边界’O’(包括边界)联通的区域外,其余全部修改为’X’,会显的很麻烦。所以正难则反,我们可以先把与边界’O’(包括边界)联通的区域修改为其他字符,再遍历整个数组,把剩余的’O’区域修改为’X’,最后把原来修改为的其他字符还原为’O’,这样也可以解决问题,并且整个代码书写也更清晰。当然,这里的bfs算法也不止使用一次,所以也要写成函数,它的作用是把与边界’O’(包括边界)联通的区域修改为其他字符。
细节/技巧问题:
参考前面三题
代码实现:
class Solution
{int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};int m, n;bool vis[201][201];
public:void solve(vector<vector<char>>& board) {m = board.size(), n = board[0].size();// 先把边界上的'O'区域改为无关字符for(int i = 0; i < m; i++){if(board[i][0] == 'O') bfs(board, i, 0);if(board[i][n-1] == 'O') bfs(board, i, n-1);}for(int j = 0; j < n; j++){if(board[0][j] == 'O') bfs(board, 0, j);if(board[m-1][j] == 'O') bfs(board, m-1, j);}// 再遍历矩阵,把所有'O'改为'X'for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(board[i][j] == 'O' && !vis[i][j])board[i][j] = 'X';}}// 最后还要把前面改过的'.'还原为'O'for(int i = 0; i< m; i++){for(int j = 0; j < n; j++)if(board[i][j] == '.')board[i][j] = 'O';}}void bfs(vector<vector<char>>& board, int i, int j){queue<pair<int ,int>> q;q.push({i ,j});vis[i][j] = true;board[i][j] = '.';while(q.size()){auto[a,b] = q.front();q.pop();for(int k = 0; k < 4; k++){int x = a+dx[k], y = b+dy[k];if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && board[x][y] == 'O'){q.push({x, y});vis[x][y] = true;board[x][y] = '.';}}}}
};
3, 算法总结
bfs是一种十分经典的算法,它总是使用队列来完成层序遍历,其实就是以当前位置为中心,再进行上下左右四个方向的位置识别,查找与统计。通过前面四道题的介绍,我们也可以发现bfs算法也是有大致的固定模版,只不过每个bfs算法在解决问题的过程中的作用不同而已。
相关文章:
【经典算法】BFS_FloodFill算法
目录 1, 算法介绍2,算法原理和代码实现(含题目链接)733.图像渲染200.岛屿的数量695.岛屿的最大面积130.被围绕的区域 3, 算法总结 1, 算法介绍 FloodFill(洪水灌溉) 算法介绍: 假设一个 4 * 4 的方格代表一块土地&am…...
RocketMQ之Topic主题详解
Topic概念定义 主题:RocketMQ中消息传输和存储的顶层容器,用于标识同类业务中逻辑的消息,可理解为消息的分类,主题消息的分类取决于业务,要发送的业务消息最好单独是一个Topic主题,以保证互相不被干扰Topi…...
实战OpenCV之图像显示
基础入门 OpenCV提供的功能非常多,图像显示是最基础也是最直观的一部分。它让我们能够直观地看到算法处理后的效果,对于调试和验证都至关重要。在OpenCV中,图像显示主要依赖于以下四个关键的数据结构和函数。 1、Mat类。这是OpenCV中最基本的…...
I2C的10-bit地址空间
10-bit地址空间: I2C支持 10-bit的设备地址,此时的时序如下图所示: 在 10-bit地址的 I2C系统中,需要两个帧来传输 slave的地址。第一个帧的前 5个 bit固定为 b11110,后接 slave地址的高 2位,第 8位仍然是 …...
TinyWebserver的复现与改进(6):定时器处理非活动连接
如果客户端长时间没有动作,会占用了许多连接资源,严重影响服务器的性能。因此需要通过实现一个服务器定时器,处理这种非活跃连接,释放连接资源。 定时器处理流程 SIGALARM触发:整个流程开始于一个 SIGALARM 信号&…...
ThinkPHP5 5.0.23 远程代码执行漏洞
目录 1、启动环境 2、漏洞利用 3、更改传参方式 4、修改参数 5、发送数据 1、启动环境 docker-compose up -d 2、访问靶机ip端口号8080 2、漏洞利用 使用burpsuite抓包软件抓包 3、更改传参方式 将 GET传参改为POST传参 4、修改参数 url参数 /index.php?scaptcha post参…...
C++鼠标键盘操作自动化
C鼠标键盘操作自动化 #pragma once #include <Windows.h> enum KEYS{A 65,W87,S83,D68,SHIFTVK_LSHIFT,ALT18,Tilde 126,//~TABVK_TAB,B66,SPACEVK_SPACE,ESCVK_ESCAPE,Q81 }; enum MOUSE {ML,MW,MR//左,中,右 }; class simulator//模拟器 { pu…...
多个主流Python GUI库全面解析,助你用Python轻松构建精美界面
Python 作为一门易学易用的编程语言,在各个领域都拥有广泛的应用。而 GUI (Graphical User Interface) 编程更是让 Python 变得更加灵活,可以帮助我们创建各种各样的桌面应用,为用户提供直观的交互体验。本文将介绍几个Python GUI 编程中常用…...
Kotlin学习-01创建kotlin学习
安装idea https://www.jetbrains.com/zh-cn/ 创建项目 选择kotlin 修改Main.kt fun main() {print("Hello World!") }运行...
Java、python、php版的企业单位考勤打卡管理系统的设计与实现(源码、调试、LW、开题、PPT)
💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流&…...
在IntelliJ IDEA中使用Git推送项目
去gitee网站注册用户 gitee网站地址:https://gitee.com/ github网站地址:https://github.com/ 一、创建仓库 以下以gitee为例进行介绍,github操作雷同。 1、创建仓库 点击页面右上方的"“并选择"创建仓库” 2、设置仓库相关信息 首先输入仓库名&…...
CNN代码实战
CNN的原理 从 DNN 到 CNN (1)卷积层与汇聚 ⚫ 深度神经网络 DNN 中,相邻层的所有神经元之间都有连接,这叫全连接;卷积神经网络 CNN 中,新增了卷积层(Convolution)与汇聚(…...
迁移学习代码复现
一、前言 说来可能令人难以置信,迁移学习技术在实践中是非常简单的,我们仅需要保留训练好的神经网络整体或者部分网络,再在使用迁移学习的情况下把保留的模型重新加载到内存中,就完成了迁移的过程。之后,我们就可以像训练普通神经网络那样训练迁移过来的神经网络了。 我们…...
Elasticsearch(ES)常用命令
常用运维命令 一、基本命令1.1、查看集群的健康状态1.2、查看节点信息1.3、查看索引列表1.4、创建索引1.5、删除索引1.6、关闭索引1.7、打开索引1.8、查看集群资源使用情况(各个节点的状态,包括磁盘,heap,ram的使用情况࿰…...
C/C++ 不定参函数
C语言不定参函数 函数用法总结 Va_list 作用:类型定义,生命一个变量,该变量被用来访问传递给不定参函数的可变参数列表用法:供后续函数进调用,通过该变量访问参数列表 typedefchar* va_list; va_start 作用ÿ…...
C语言——函数专题
1.概念 在C语言中引入函数的概念,有些翻译为子程序。C语言中的函数就是一个完成某项特定任务的一小段代码,这个代码是有特殊的写法和调用方法的。一般我们可以分为两种函数:库函数和自定义函数。 2.库函数 C语言国际标准ANSIC规定了一些常…...
springboot打可执行jar包
1. pom文件如下 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><m…...
【SQL】科目种类
目录 题目 分析 代码 题目 表: Teacher ------------------- | Column Name | Type | ------------------- | teacher_id | int | | subject_id | int | | dept_id | int | ------------------- 在 SQL 中,(subject_id, dept_id) 是该表的主键。 该表…...
【深度学习】【语音】TTS,最新TTS模型概览,扩散模型TTS,MeloTTS、StyleTTS2、Matcha-TTS
文章目录 基础介绍对比基础介绍 MeloTTS: MeloTTS 是 MyShell.ai 开发的一个多语言语音合成模型,支持包括英语、西班牙语、法语、中文、日语和韩语等多种语言。它以高质量的语音合成为特色,尤其擅长处理中英混合内容。该模型优化了在 CPU 上的实时推理能力,使其在多种应用场…...
【论文笔记】LION: Linear Group RNN for 3D Object Detection in Point Clouds
原文链接:https://arxiv.org/abs/2407.18232 简介:Transformer在3D点云感知任务中有二次复杂度,难以进行长距离关系建模。线性RNN则计算复杂度较低,适合进行长距离关系建模。本文提出基于窗口的网络线性组RNN(即对分组…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

