FloodFill算法---BFS

目录

一、前言

二、算法模板套路

2.1 创建所需的全局变量:

2.2 BFS模板:

2.3 细节处理:

三、例题练习

3.1 例题1:图像渲染

3.2 例题2:岛屿数量

3.3 例题3:岛屿的最大面积

3.4 例题4:被围绕的区域


一、前言

在这之前我们已经学习了如何使用 DFS 解决 FloodFill 算法,如果有友友对 FloodFill 算法不太熟悉的话可以先看看我之前写的文章:FloodFill算法---DFS。里面详细介绍了什么是FloodFill算法和如何使用DFS来解决。通常 FloodFill 算法使用 DFS 或者 BFS 都可以,DFS 的代码会简洁一些,但是 BFS 可以用来解决最短路问题拓扑排序。所以本文章可以说是为了后续使用 BFS 解决最短路问题和拓扑排序打下基础。

• 关于BFS的遍历特性:若初始点为左上角,遍历特性如下图所示。

二、算法模板套路

2.1 创建所需的全局变量:

最好设置为静态,因为非静态只有在leetcode上才行,在竞赛中都是要我们自己写Main类的因为main是静态方法所以在方法外面的全局变量要设置为静态的才能被main方法调用。

static boolean[][] vis;//( 不一定要有)static int[ ] dx = {0 , 0 , 1 , -1 };static int[ ] dy = {1 , -1 , 0 , 0 };

• vis这个布尔类型数组来标记我们已经走过的路,防止重复走导致死循环:

还有一种可以不用创建 vis 来标记,直接修改原来数据的值,这个如果是在面试的时候要问一下面试官,原来数组的数值是否可以修改。

• 利用dx,dy 来实现上下左右移动(如果是8个方向的也行):

for(int k = 0;k < 4;k++){int x = i + dx[k];int y = j + dy[k];
}

 如果是 8 个方向的话可以先画出下图。

在把黄色对应的8个位置写入到dx和dy中。例如:

下面这个例子是从上到下,从左到右写的。

static int[] dx = {-1,-1,-1,0,0,1,1,1};
static int[] dy = {-1,0,1,-1,1,-1,0,1};

2.2 BFS模板:

我们利用 int[ ]来存储坐标。

• 至于要不要回溯,要根据题目要求什么来进行决定。

• x >= 0 && x < n && y >= 0 && y < m 这个可以说是默写了,因为这就是防止越界,每道题目都是这么写的。

public void bfs(char[][] grid, int i, int j) {Queue<int[]> queue = new LinkedList<>();queue.add(new int[] { i, j });while (!queue.isEmpty()) {int[] tmp = queue.poll();int a = tmp[0];int b = tmp[1];vis[a][b] = true;///1for (int k = 0; k < 4; k++) {int x = a + dx[k];int y = b + dy[k];if(x >= 0 && x < n && y >= 0 && y < m && !vis[x][y]){queue.add(new int[]{x,y});vis[x][y] = true;///2}}}}

2.3 细节处理:

不知道大家有没有注意到在模板那里,我在代码里标记了1和2,现在我要问问友友们,2处的代码能否省略?

答:不能省略。因为如果不加上代码2的话,有些节点会重复进入,导致代码超时(这个要想清楚,因为我当时没有代码2,检查代码检查半天才找到😭😭😭)。友友们在学完下面几个例题后可以去  岛屿数量 上面试一下。

如果疑惑哪个元素会被重复进入,可以看看下图(有点丑😭),蓝色元素会被两个红色元素扩散重复进入。如果加上代码 2 就不会有这种情况。

三、例题练习

3.1 例题1:图像渲染

• 题目链接:图像渲染

• 问题描述:

有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。

你也被给予三个整数 sr ,  sc 和 newColor 。你应该从像素 image[sr][sc] 开始对图像进行 上色填充 。

为了完成 上色工作 ,从初始像素开始,记录初始坐标的 上下左右四个方向上 像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应 四个方向上 像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为 newColor 。

最后返回 经过上色渲染后的图像 

• 解题思路:

可以利用深搜(DFS)或者宽搜(BFS),遍历到与该点相连的所有像素相同的点,然后将其修改成指定的像素即可。因为这个可以直接在原来数组上修改,那么我们就不用创建 vis 来标记我们已经走过的路,由于本文章主要讲解 BFS 所以本题采用 BFS 来进行解决。最后一个小优化,如果要修改的值和原来的值相同,那么直接返回即可。

• 代码编写:

class Solution {int[] dx = {0,0,-1,1};int[] dy = {1,-1,0,0};public int[][] floodFill(int[][] image, int sr, int sc, int color) {if(image[sr][sc] == color){//处理边界情况return image;}int n = image.length;int m = image[0].length;int prev = image[sr][sc];Queue<int[]> queue = new LinkedList<>();queue.add(new int[]{sr,sc});//创建队列while(!queue.isEmpty()){int[] tmp = queue.poll();int i = tmp[0],j = tmp[1];image[i][j] = color;for(int k = 0;k < 4;k++){int x = i + dx[k];int y = j + dy[k];if(x >= 0 && x < n && y >= 0 && y < m && image[x][y] == prev){queue.offer(new int[]{x,y});}}}return image;}
}

3.2 例题2:岛屿数量

• 题目链接:岛屿数量

• 问题描述:

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

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

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

• 解题思路:

遍历整个矩阵,每次找到一块陆地的时候,岛屿数量 + 1,并且将这个陆地相连的所有陆地,全都修改,这样我们下次遍历到这里就不会影响最终的结果。当我们遍历完全部的矩阵的时候,岛屿数量也就找到了。

• 代码编写:

我们直接在原数据上修改,不用 vis 了。

class Solution {int[] dx = { 0, 0, 1, -1 };int[] dy = { 1, -1, 0, 0 };int n;int m;public int numIslands(char[][] grid) {int count = 0;// 最后统计岛屿数量n = grid.length;m = grid[0].length;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (grid[i][j] == '1') {//找到陆地bfs(grid, i, j);//标记count++;}}}return count;}public void bfs(char[][] grid, int i, int j) {Queue<int[]> queue = new LinkedList<>();queue.add(new int[] { i, j });while (!queue.isEmpty()) {int[] tmp = queue.poll();int a = tmp[0];int b = tmp[1];grid[a][b] = '2';///1for (int k = 0; k < 4; k++) {int x = a + dx[k];int y = b + dy[k];if(x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == '1'){queue.add(new int[]{x,y});grid[x][y] = '2';///2}}}}
}

如果没有代码块 2 就会出现下面这种情况:超时啦!

 

3.3 例题3:岛屿的最大面积

• 题目链接:岛屿的最大面积

• 问题描述:

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

• 解题思路:

遍历整个矩阵,每当遇到一块土地的时候,就用深搜或者宽搜将与这块土地相连的整个岛屿的面积计算出来。 然后在搜索得到的所有的岛屿面积求一个最大值即可。 在搜索过程中,为了防止搜到重复的土地。也可以将原始矩阵的 1 修改成 2,当然我们也可以使用 vis 数组来保存我们走过的路。

• 代码编写:

class Solution {int n,m;int[] dx = {0,0,1,-1};int[] dy = {1,-1,0,0};public int maxAreaOfIsland(int[][] grid) {int max = 0;n = grid.length;m = grid[0].length;for(int i = 0;i < n;i++){for(int j = 0;j < m;j++){if(grid[i][j] == 1){max = Math.max(bfs(grid,i,j),max);//找出最大面积}}}return max;}public int bfs(int[][] grid,int i,int j){Queue<int[]> queue = new LinkedList<>();queue.offer(new int[]{i,j});int count = 1;while(!queue.isEmpty()){int[] tmp = queue.poll();int a = tmp[0],b = tmp[1];grid[a][b] = 2;for(int k = 0;k < 4;k++){int x = a + dx[k];int y = b + dy[k];if(x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == 1){count++;queue.offer(new int[]{x,y});grid[x][y] = 2;//直接修改原数组的值即可。}}}return count;//返回岛屿的数量}
}

3.4 例题4:被围绕的区域

• 题目链接:被围绕的区域

• 问题描述:

给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

• 解题思路:

我们可以发现直接做难度还是挺大的,要处理的边界和各种条件还是比较多的,这里我们采用一种正难则反的思路来解决这道问题。

1. 先处理边界上的 O 区域,因为这个 O 一定不会是被围绕的,所以遍历边界来一次搜索即可。

2. 扫描矩阵,进行还原。

这题我们采用 vis 来标记我们走过的路。

• 代码编写:

class Solution {boolean[][] vis;int[] dx = {0,0,1,-1};int[] dy = {1,-1,0,0};int n,m;public void solve(char[][] board) {n = board.length;m = board[0].length;vis = new boolean[n][m];//遍历边界for(int i = 0;i < m;i++){//第一行if(board[0][i] == 'O'){bfs(board,0,i);}//最后一行if(board[n - 1][i] == 'O'){bfs(board,n - 1,i);}}for(int i = 0;i < n;i++){//第一列if(board[i][0] == 'O'){bfs(board,i,0);}//最后一列if(board[i][m - 1] == 'O'){bfs(board,i,m - 1);}}//还原矩阵for(int i = 0;i < n;i++){for(int j = 0;j < m;j++){if(board[i][j] == 'O' && !vis[i][j]){board[i][j] = 'X';}}}}public void bfs(char[][] board,int i,int j){vis[i][j] = true;Queue<int[]> queue = new LinkedList<>();queue.offer(new int[]{i,j});while(!queue.isEmpty()){int[] tmp = queue.poll();int a = tmp[0];int b = tmp[1];for(int k = 0;k < 4;k++){int x = a + dx[k];int y = b + dy[k];if(x >= 0 && x < n && y >= 0 && y < m && board[x][y] == 'O' && !vis[x][y]){queue.offer(new int[]{x,y});vis[x][y] = true;}}}}
}

• 总结:BFS 来解决 FloodFill 类问题的模板是比较固定的,希望友友们要掌握好,因为我们后续还要利用 BFS 来解决最短路问题和拓扑排序。算法模板里面的细节处理一定要想清楚,其他的其实和之前 DFS 解决这类问题是一样的。

结语:

其实写博客不仅仅是为了教大家,同时这也有利于我巩固知识点,和做一个学习的总结,由于作者水平有限,对文章有任何问题还请指出,非常感谢。如果大家有所收获的话还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。

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

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

相关文章

在做题中学习(54):点名

LCR 173. 点名 - 力扣&#xff08;LeetCode&#xff09; 此题有不同的几种解法&#xff1a; 解法一&#xff1a;暴力枚举 O(n); 解法二&#xff1a;哈希表 把原数组丢入哈希表&#xff0c;遍历哈希表&#xff0c;看看哪个数值为0即可。 O(n)空间O(n)时间 解法三&…

OpenAI推出新模型GPT-4o:可实时交互,检测人的情绪,支持多模态输出

GPT-4o作为OpenAI新发布的人工智能模型&#xff0c;据官方及媒体报道&#xff0c;是面向全球用户发布的&#xff0c;包括中国在内的用户理论上应该能够通过相应平台和应用访问。不过&#xff0c;实际可用性还需考虑地区政策、网络访问限制以及具体平台是否在中国有本地化服务等…

1694jsp宿舍管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 宿舍管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统采用web模式&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库…

网络安全快速入门(十一)vi/vim

11.1 了解vi 前面我i们已经在基础命令中大致了解了vi&#xff0c;本章我们针对vi来细讲一下&#xff0c;vi和vim 11.1.1 什么是vi/vim&#xff1f; vi和vim&#xff0c;都是一个模块化的文本编辑工具&#xff0c;换句话讲&#xff0c;通过vi下的一系列的命令&#xff0c;可以实…

Redis 源码安装和入门介绍

Linux下的redis源码安装 redis介绍 Redis 是一个开源&#xff08;BSD许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构&#xff0c;如 字符串&#xff08;strings&#xff09;&#xff0c;…

专访安克创新CEO阳萌:仿生算法与存算一体芯片的兴起

在这篇博客中&#xff0c;我们将探讨人工智能的未来发展方向&#xff0c;特别是围绕大模型、存算一体芯片以及仿生算法的讨论。通过对安克创新CEO阳萌的专访内容进行分析&#xff0c;我们将尝试解答一些关于AI发展的关键问题&#xff0c;并对未来的技术趋势进行预测。 引言 …

AD原理图设置:如何在编译工程时,报未连接线或引脚错误

如下图&#xff0c;AD默认在编译原理图时&#xff0c;如果出现未连接的引脚或线时&#xff0c;并不会报相关的错误&#xff0c;这样做其实很危险 所以&#xff0c;我们应该让它提示错误 具体配置方法&#xff1a; 1、找到工程选项 2、切换到第二个选项“Connection Matrix”&a…

OBS插件--源录制

源录制 将应用这个滤镜的源录制成视频保存下来&#xff0c;可以选择音轨&#xff0c;也可以针对应用此滤镜的源单独的推流等。 如果在直播或录制视频的过程中场景里面布置了多个源&#xff0c;而只想保存其中一个源的视频或音频这个插件非常使用。 下面截图演示下操作步骤&a…

面试中的算法(查找缺失的整数)

在一个无序数组里有99个不重复的正整数&#xff0c;范围是1~100&#xff0c;唯独缺少1个1~100中的整数。如何找出这个缺失的整数? 一个很简单也很高效的方法&#xff0c;先算出1~100之和&#xff0c;然后依次减去数组里的元素&#xff0c;最后得到的差值&#xff0c;就是那个缺…

数据库入门(sql文档+命令行)

一.基础知识 1.SQL&#xff08;Structured Query Language&#xff09;结构化查询语言分类&#xff1a; DDL数据定义语言用来定义数据库对象&#xff1a;数据库、表、字段DML数据操作语言对数据库进行增删改查DQL数据查询语言查询数据库中表的信息DCL数据控制语言用来创建数据…

安装adobe系列,提示错误代码146解决办法

安装Adobe系列产品如PS、PR、Lrc等产品时&#xff0c;会因为各种各样的错误导致安装失败&#xff01;今天小编为大家带来的是安装adobe系列&#xff0c;提示错误代码146解决办法&#xff0c;收藏起来吧&#xff01; 方法一&#xff1a;就是传说中的万能大法&#xff0c;关机重启…

苍穹外卖项目---------收获以及改进(9-12)

①Spring Task-------实现系统定时任务 概念&#xff1a; 应用场景&#xff1a; 使用步骤&#xff1a; 实现订单超时和前一天派送中的订单的自动任务处理&#xff1a; Component Slf4j public class Mytask {Autowiredprivate OrderServiceimpl orderServiceimpl;/*** 处理订…

基于uniapp+vue3+ts小程序项目实战之项目初始化

&#x1f680; 作者 &#xff1a;“二当家-小D” &#x1f680; 博主简介&#xff1a;⭐前荔枝FM架构师、阿里资深工程师||曾任职于阿里巴巴担任多个项目负责人&#xff0c;8年开发架构经验&#xff0c;精通java,擅长分布式高并发架构,自动化压力测试&#xff0c;微服务容器化k…

OpenCV使用 Kinect 和其他兼容 OpenNI 的深度传感器(75)

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇:使用 OpenCV 创建视频(74) 下一篇 :OpenCV使用 Orbbec Astra 3D 相机(76) 目的&#xff1a;​ 通过 VideoCapture 类支持与 OpenNI 兼容的深度传感器&#xff08;Kinect、XtionPRO 等&#xff09;。…

【数据结构】解密链表之旅(单链表篇)

前言 哈喽大家好&#xff0c;我是野生的编程萌新&#xff0c;首先感谢大家的观看。数据结构的学习者大多有这样的想法&#xff1a;数据结构很重要&#xff0c;一定要学好&#xff0c;但数据结构比较抽象&#xff0c;有些算法理解起来很困难&#xff0c;学的很累。我想让大家知道…

QLExpress入门及实战总结

文章目录 1.背景2.简介3.QLExpress实战3.1 基础例子3.2 低代码实战3.2.1 需求描述3.2.1 使用规则引擎3.3.2 运行结果 参考文档 1.背景 最近研究低代码实现后端业务逻辑相关功能&#xff0c;使用LiteFlow作为流程编排后端service服务, 但是LiteFlow官方未提供图形界面编排流程。…

大型语言模型自我进化综述

24年4月来自北大的论文“A Survey on Self-Evolution of Large Language Models”。 大语言模型&#xff08;LLM&#xff09;在各个领域和智体应用中取得了显着的进步。 然而&#xff0c;目前从人类或外部模型监督中学习的LLM成本高昂&#xff0c;并且随着任务复杂性和多样性的…

InLine Chat功能优化对标Github Copilot,CodeGeeX带来更高效、更直观的编程体验!

VSCode中的CodeGeeX 插件上线InLine Chat功能后&#xff0c;收到不少用户的反馈&#xff0c;大家对行内交互编程这一功能非常感兴趣。近期我们针对这个功能再次进行了深度优化&#xff0c;今天详细介绍已经在VSCode插件v2.8.0版本上线的 CodeGeeX InLine Chat功能&#xff0c;以…

Visual Studio 2022专业版安装步骤

Visual studio下载 首先进入下载官网,下载2022专业版 我勾选了以下几个和c#开发有关的&#xff0c;后面缺什么还可以再安装所有以少勾了问题也不大 然后改一下安装位置,点击安装 专业版秘钥激活 打开设置选择帮助,注册vs 专业版密钥: TD244-P4NB7-YQ6XK-Y8MMM-YWV2J

【MinGW】MinGW-w64的安装及配置教程

目录 &#x1f31e;1. MinGW简介 &#x1f31e;2. MinGW安装详情 &#x1f30a;2.1 资源包获取 &#x1f30a;2.2 安装详情 &#x1f31e;1. MinGW简介 MinGW (Minimalist GNU for Windows) 是一个在 Windows 平台上开发软件的开发工具集合。它提供一组用于编译 Windows 应…