【算法】BFS系列之 FloodFill 算法

【ps】本篇有 4 道 leetcode OJ。

 

目录

一、算法简介

二、相关例题

1)图像渲染

.1- 题目解析

.2- 代码编写

2)岛屿数量

.1- 题目解析

.2- 代码编写

3)岛屿的最大面积

.1- 题目解析

.2- 代码编写

4)被围绕的区域

.1- 题目解析

.2- 代码编写


一、算法简介

        FloodeFill算法即填充算法,原理就是从一个点开始向四周扩散,向周围可以走到的点填充颜色,直到将可扩散到的点全部填充颜色。

        通常使用下面两种方法解决FloodFill算法问题:

  • BFS (宽搜)算法通常使用队列实现,将起始像素点加入队列中,并不断扩展队列中的像素点,直到队列为空为止。
  • DFS(深搜) 算法通常使用递归实现,在处理当前像素点的相邻像素点时,递归调用 DFS 函数,不断深入直到无法找到相邻像素为止。

         假设这一块4*4的方格是一块土地,有凸起的地方,也有凹陷的地方(凹陷的地方用负数表示)。此时下大雨发洪水,会把凹陷的地方填满。绿色圈起来的属于一块区域(上下左右四个方向,有时候题目也会问八个方向包括斜着相连的),题目会问有多少块区域被填满,或者问被填满的最大区域是哪个,或某一块区域的边长是多少。但是本质都是在一块区域找性质相同的连通块

  • DFS:深度优先遍历(递归):从某一点开始一条路走到黑。以最右列的为例,从-1出发,向下->-2->-10->-12,此时发现-12的上下左右都走不了,在拐回去到-10,然后发现-10左边可以走->-4->-3。

  • BFS:宽度优先遍历:一层一层拨开。还是以最右边为例,从-1开始拓展一层(上下左右)发现能把-2扩展出来,接着继续扩展一层上下左右,-3和-10扩展出来;接着在扩展一层上下左右,把-4和-12扩展出来。 

 

int dx[4] = {0, 0 , -1, 1}; 
int dy[4] = {1, -1 , 0, 0};
// i点加dx,dy就是i点的上下左右的下标 

二、相关例题

1)图像渲染

733. 图像渲染

 

.1- 题目解析

        利用 BFS 遍历到与某点相连的所有像素相同的点,然后将其修改成指定的像素即可。

.2- 代码编写

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(), n = image[0].size();queue<PII> q;q.push({sr, sc});while (q.size()) {auto [a, b] = q.front();image[a][b] = color;q.pop();for (int i = 0; i < 4; i++) { //遍历相邻的四个方向int x = a + dx[i], y = b + dy[i];if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == prev) {q.push({x, y});}}}return image;}
};

2)岛屿数量

200. 岛屿数量

.1- 题目解析

        被水(0)围起来的相连的陆地(1)才算一座岛屿。

        我们可以遍历整个矩阵,每次找到一块陆地的时候,即找到了一个岛屿,就将其记入最终结果,同时将这个岛屿,全部变成海洋(由1改为0),这样的话,下次遍历到这个岛屿的时候,它已经是海洋了,不会影响最终结果。其中,变成海洋的操作,可以利用 BFS 解决。

        但如果在面试中,面试官要求另外不能直接修改原始矩阵,那我们还可以用到一个全局的 bool 类型的矩阵,来记录陆地是否被遍历过。

.2- 代码编写

class Solution {int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};bool vis[301][301];//记录陆地是否被遍历过int m, n;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]) {ret++;bfs(grid, i, j); //将这块陆地全都标记一下}}}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;}}}}
};

3)岛屿的最大面积

695. 岛屿的最大面积

.1- 题目解析

        这道题是上一道题的变形。

        我们只要在遍历矩阵寻找岛屿的时候,多一步来统计一下当前找出的岛屿面积即可。

.2- 代码编写

class Solution {int dx[4]={0,0,1,-1};int dy[4]={1,-1,0,0};int m,n;bool vis[51][51];
public:int maxAreaOfIsland(vector<vector<int>>& 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]){ret=max(bfs(grid,i,j),ret);}}}return ret;}int bfs(vector<vector<int>>& grid,int i,int j){int ret=0;//统计岛屿面积(1的个数)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;}
};

4)被围绕的区域

130. 被围绕的区域

.1- 题目解析

        不难想到,可以直接通过 bfs 将所有被 'X' 围起来的 'O' 修改为 'X',但位于矩阵边缘的 'O' 其实是不必修改的,此时又该如何处理呢?

        我们可以选择正难则反,先利用 bfs 将与边缘相连的 'O' 区域修改成无关字符,然后重新遍历矩阵,将没有标记过的 'O' 全修改成 'X' 即可,再把无关字符全还原成'O'。

.2- 代码编写

class Solution {int dx[4]={0,0,1,-1};int dy[4]={1,-1,0,0};int m,n;
public:void solve(vector<vector<char>>& board) {m=board.size(),n=board[0].size();// 1. 先处理边界上的 'O' 联通块,全部修改成 '.'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);}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);}// 2. 还原for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(board[i][j]=='O')board[i][j]='X';else 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});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 && board[x][y]=='O'){q.push({x,y});board[x][y]='.';}}}}};

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

3DMAX动画渲染一百帧云渲染解决方案!

随着数字媒体快速发展&#xff0c;3D动画以其逼真的视觉效果和动态表现力&#xff0c;成为众多行业的首选。然而&#xff0c;高质量的3D动画渲染往往需要大量的计算资源。对于3DMAX动画渲染的一百帧&#xff0c;该如何的通过云渲染技术高效处理呢&#xff0c;我们一起来简单看看…

大中小企业应该如何选择PLM系统?PLM系统最新选型指南攻略

在当今竞争激烈的市场环境中&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;系统已成为企业不可或缺的工具&#xff0c;它帮助企业有效地管理从产品设计到淘汰的整个生命周期。然而&#xff0c;不同规模的企业在选择PLM系统时面临着不同的挑战和需求。本文将分析小型…

云计算实训50——Kubernetes基础命令、常用指令

一、Kubernetes 自动补齐 # 安装自动补齐软件 [rootmaster ~]# yum -y install bash-completion # 临时开启自动补齐功能 [rootmaster ~]# source # 永 久开启自动补齐功能 [rootmaster ~]# echo "source > ~/.bashrc 二、Kubernetes 基础命令 kubectl [command] …

C++伟大发明--模版

C起初是不受外界关注的&#xff0c;别人觉得他和C语言没有本质上的区别&#xff0c;只是方便些&#xff0c;直到祖师爷发明了模版&#xff0c;开始和C语言有了根本的区别。 我们通过一个小小的例子来搞清楚什么是模版&#xff0c;模版的作用到底有多大&#xff0c;平时我们想要…

【Python报错已解决】 Requests.exceptions.ProxyError: HTTPSConnectionPool

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

上证50股指期权如何交易?

今天期权懂带你了解上证50股指期权如何交易&#xff1f;上证50期权的交易是一个涉及多个步骤和策略的过程。 上证期权 上证期权是指在上海证券交易所交易的期权合约&#xff0c;主要包括上证50ETF期权等。它是一种金融衍生品&#xff0c;给予持有者在特定日期以约定价格买入或…

【数据结构与算法 | 灵神题单 | 自底向上DFS篇】力扣508, 1026, 951

1. 力扣508&#xff1a;出现次数最多的子树元素和 1.1 题目&#xff1a; 给你一个二叉树的根结点 root &#xff0c;请返回出现次数最多的子树元素和。如果有多个元素出现的次数相同&#xff0c;返回所有出现次数最多的子树元素和&#xff08;不限顺序&#xff09;。 一个结…

【项目设计】Facial-Hunter

目录 一、项目介绍 二、开发环境以及技术 三、项目架构设计 3.1 项目总体架构 3.2 客户端架构 3.3 主服务端架构 3.4 处理服务端架构 3.5 数据库设计 四、FaceNet 五、代码实现 一、项目介绍 该项目是基于深度学习与负载均衡的人脸识别系统 该项目主要由三个部分组…

CytoTRACE2单细胞分化潜力预测工具学习

开发者在github中把关键点介绍的很清楚了。 1、根据细胞的分化潜能对细胞进行分类&#xff1a; totipotent(多谱系分化的全能)—pluripotent(多谱系分化的多能)—multipotent(谱系限制分化的多能)—oligopoten(谱系限制分化的寡能)—unipotent(谱系限制分化的单能)—differen…

裸土检测算法实际应用、裸土检测算法样本、裸土检测算法精准检测

裸土检测算法是一种前沿的图像识别技术&#xff0c;它通过利用先进的图像处理技术和机器学习算法&#xff0c;从卫星图像、无人机拍摄的图像或其他地面监测数据中提取出裸土区域&#xff0c;并对其进行精确的分类和分析。 与传统的地面勘察方法相比&#xff0c;裸土检测算法具有…

Redisson分布式锁分析,可重入、可续锁(看门狗)

前言 在此说明&#xff0c;本文章不只是讲一些抽象的概念&#xff0c;而是可落地的&#xff0c;在日常工作中基本上进行修改一下便可以使用。书接上回&#xff0c;上篇自研分布式锁的文章使用是一个自己手写的一个分布式锁&#xff0c;按照JUC里面java.util.concurrent.locks.L…

子查询优化

MySQL学习大纲 我的数据库学习大纲 1、什么是子查询&#xff1a; 1.MySQL 从 4.1 版本开始支持子查询&#xff0c;使用子查询可以进行 SELECT 语句的嵌套查询&#xff0c;即一个 SELECT 查询的结果作为另一个 SELECT 语句的条件。子查询可以一次性完成很多逻辑上需要多个步骤才…

渗透测试综合靶场 DC-2 通关详解

一、准备阶段 准备工具如Kali Linux&#xff0c;下载并设置DC-2靶场机。确保攻击机和靶机在同一网络段&#xff0c;通常设置为桥接模式或NAT模式。 1.1 靶机描述 Much like DC-1, DC-2 is another purposely built vulnerable lab for the purpose of gaining experience in …

社区志愿者服务系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;志愿者管理&#xff0c;社区管理&#xff0c;活动类型管理&#xff0c;志愿者活动管理&#xff0c;活动报名管理&#xff0c;活动签到管理&#xff0c;证书信息管理&#xff0c;系统管理 微信端账号功…

保护您的企业免受网络犯罪分子侵害的四个技巧

在这个日益数字化的时代&#xff0c;小型企业越来越容易受到网络犯罪的威胁。网络犯罪分子不断调整策略&#xff0c;并使用人工智能来推动攻击。随着技术的进步&#xff0c;您的敏感数据面临的风险也在增加。 风险的不断增大意味着&#xff0c;做好基本工作比以往任何时候都更…

arduino ide开发esp32-wroom-32E

这个芯片esp32-wroom-32E拿到手&#xff0c;在arduino里试试看 下面是开发板的添加地址 https://dan.drown.org/stm32duino/package_STM32duino_index.json 放到首选项里重启 淘宝镜像包 https://dl.espressif.com/dl/package_esp32_index.json 清华大学镜像包 http…

Java--stream流、方法引用

Stream流 - Stream流的好处 - 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义 - Stream流把真正的函数式编程风格引入到Java中 - 代码简洁 - Stream流的三类方法 - 获取Stream流 - 创建一条流水线,并把数据放到流水线上准备进行操作 - 中间方法 - 流水线上的操作 - 一次…

bmp格式图片怎么转换jpg?这几种转换方法超级好用!

bmp格式图片怎么转换jpg&#xff1f;BMP格式&#xff0c;这一历史悠久的图像编码方式&#xff0c;正逐渐在数字时代的浪潮中显得力不从心&#xff0c;其边缘化的趋势愈发明显&#xff0c;这一现象的根源&#xff0c;在于BMP格式固有的局限性难以匹配现代用户对于图像处理的多元…

深入探索Android开发之Java核心技术学习大全

Android作为全球最流行的移动操作系统之一&#xff0c;其开发技能的需求日益增长。本文将为您介绍一套专为Android开发者设计的Java核心技术学习资料&#xff0c;包括详细的学习大纲、PDF文档、源代码以及配套视频教程&#xff0c;帮助您从Java基础到高级特性&#xff0c;再到A…

【限流算法】

文章目录 介绍算法原理适用场景令牌通算法实现限流算法 介绍 令牌桶算法是网络流量整形&#xff08;Traffic Shaping&#xff09;和速率限制&#xff08;Rate Limiting&#xff09;中最常使用的一种算法。典型情况下&#xff0c;令牌桶算法用来控制发送到网络上的数据的数目&a…