【算法】bfs解决FloodFill问题

2024-04-13 18:36

本文主要是介绍【算法】bfs解决FloodFill问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

个人主页 : zxctscl
如有转载请先通知

题目

  • FloodFill算法
  • 1. 733. 图像渲染
    • 1.1 分析
    • 1.2 代码
  • 2. 200. 岛屿数量
    • 2.1 分析
    • 2.2 代码
  • 3. 695. 岛屿的最大面积
    • 3.1 分析
    • 3.2 代码
  • 4. 130. 被围绕的区域
    • 4.1 分析
    • 4.2 代码

FloodFill算法

FloodFill就是洪水灌溉,解决的就是下面这样一种模型。
解决性质相同的联通块问题,用的方法就是dfs深度优先搜索遍历:一条道走到黑,直到不能再走,不能再走就倒回去;或者是bfs宽度优先搜索遍历:一层一层剥开

1. 733. 图像渲染

在这里插入图片描述

1.1 分析

用bfs模拟流程
假设有这么一个矩阵,给的位置是(1,1)与(1,1)相连的所有像素相同的点,全部修改为2。
那么就一层一层搜索,就是从(1,1)开始搜索:
第一层从(1,1)开始的上下左右扫描,把(1,2)和(2,1)的值都修改为2;
第二层从(1,2)和(2,1)开始:(1,2)的扫描多加了(0,2);
(2,1)的扫描多了(2,0)和(3,1)
第三层从(0,2)、(2,0)和(3,1)开始:(0,2)多加了(0,3);(2,0)没有;(3,1)多了(3,2)
第四层从(0,3)、(3,2)发现没有了,层序遍历就完成了。
在这里插入图片描述

1.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 m=image.size(),n=image[0].size();int prev=image[sr][sc];//标记一下需要修改的像素值if(prev==color)return image;//处理边界情况queue<PII> q;q.push({sr,sc});while(q.size()){auto [a,b]=q.front();//取出对头q.pop();image[a][b]=color;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. 岛屿数量

在这里插入图片描述

2.1 分析

模拟一下过程
以例2模拟:从(0,0)位置开始扩展,不能扩展回去,为了不在原数组上面修改,可以给一个bool数组和原矩阵规模是一样的,然后里面如果存false,就代表这个位置没有遍历过,如果存true表示遍历过。那么从这个位置开始它的上下左右中如果有true,那么就不扫描。

在这里插入图片描述

2.2 代码

class Solution {int dx[4] = { 0,0,1,-1 };int dy[4] = { 1,-1,0,0 };  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. 岛屿的最大面积

在这里插入图片描述

3.1 分析

和上面那题类似,就加了一个在dfs里面统计一下面积,然后再返回的这些面积里面找到最大的那个就行。

3.2 代码

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 = 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(ret, bfs(grid, i, j));}}}return ret;}int bfs(vector<vector<int>>& grid, int i, int j){queue<pair<int, int>>q;q.push({ i,j });vis[i][j] = true;int count = 1;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;count++;}}}return count;}};

4. 130. 被围绕的区域

在这里插入图片描述

4.1 分析

如果直接开始模拟,那么与边缘相关的联通块就不好做。那么就从与边缘相关的连通块开始做,先遍历四条变,如果边上有0,就先对它们来一个层序遍历,然后把这些位置全部修改为无关的字符。那么接下来就只需要遍历矩阵,把里面的0都修改为x就可以,因为没有被包围的四边已经处理了,剩下的就是一定被包围的。最后在把无关的字符再改回去就可以了。
这个方法叫正难则反,先处理边界上0,改为.,再扫描完矩阵后,还原。

4.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();//先处理边界o,把他们修改为afor(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);}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]=='a')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]='a';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] = 'a';}}}}};

有问题请指出,大家一起进步吧!!!

这篇关于【算法】bfs解决FloodFill问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/900903

相关文章

qt5cored.dll报错怎么解决? 电脑qt5cored.dll文件丢失修复技巧

《qt5cored.dll报错怎么解决?电脑qt5cored.dll文件丢失修复技巧》在进行软件安装或运行程序时,有时会遇到由于找不到qt5core.dll,无法继续执行代码,这个问题可能是由于该文... 遇到qt5cored.dll文件错误时,可能会导致基于 Qt 开发的应用程序无法正常运行或启动。这种错

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2

解决JSONField、JsonProperty不生效的问题

《解决JSONField、JsonProperty不生效的问题》:本文主要介绍解决JSONField、JsonProperty不生效的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录jsONField、JsonProperty不生效javascript问题排查总结JSONField

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos