当前位置: 首页 > news >正文

【算法】【优选算法】BFS 解决 FloodFill 算法

目录

  • 一、FloodFill 算法简介
  • 二、733. 图像渲染
  • 三、200. 岛屿数量
  • 四、695. 岛屿的最⼤⾯积
  • 五、130.被围绕的区域

一、FloodFill 算法简介

FloodFill 算法,可以理解为根据洪水蔓延,以点覆面,在这个过程中对涉及的一些问题求解。

二、733. 图像渲染

题目链接:733. 图像渲染

题目描述:

题目解析:

  • 相当于给我们一个二维数组,和指定一个数组中的值为“母体”,当该位置上下左右四个方向初始值相同,就改为指定值(被传染),依次类推下去,直到全部感染或者传染不了。

解题思路:

  • 利⽤「深搜」或者「宽搜」,遍历到与该点相连的所有「像素相同的点」,然后将其修改成指定的像素即可.
  • 也就是我们使用一个队列,记录下来所有母体,出去一个母体,就将能传染的四个位置记录进队列。
  • 注意下标问题,和当全部颜色都相同时,会超出时间限制,单独处理。

解题代码:

//时间复杂度:O(N)
//空间复杂度:O(N)
class Solution {public int[][] floodFill(int[][] image, int sr, int sc, int color) {//记录开始颜色int pre = image[sr][sc];//实例二排除if(pre == color) return image;Queue<int[]> queue = new LinkedList<>();queue.add(new int[]{sr,sc});//对队列进行操作,直到空while(!queue.isEmpty()) {int[] cur = queue.poll();int x = cur[0];int y = cur[1];//下标合法且颜色相同,传染,记录上下左右if(x >= 0 && x < image.length &&y >= 0 && y < image[0].length &&pre == image[x][y]) {image[x][y] = color;queue.add(new int[]{x-1, y});queue.add(new int[]{x+1, y});queue.add(new int[]{x, y-1});queue.add(new int[]{x, y+1});}}return image;}
}

三、200. 岛屿数量

题目链接:200. 岛屿数量

题目描述:

题目解析:

  • 就是给我们一个二位字符数组,让我们求相邻字符‘1’有多少块。

解题思路:

  • 使用宽搜的思路,将每个数组元素都遍历一遍。
  • 每一次都遍历字符数组去找到每一个岛屿的登陆地,也就是每一块1的第一个1。
  • 我们引入一个标记数组(尽量不改变原数组),标记进过队列的字符数组元素下标,标记字符为0的数组下标,当标记数组全为修改后的true时,就可以返回值了。
  • 写一个死循环包含上里面的逻辑,当数组全部为0的时候结束。

解题代码:

//时间复杂度:O(M*N)
//空间复杂度:O(M*N)
class Solution {int[] dx = new int[]{0,0,1,-1};int[] dy = new int[]{1,-1,0,0};boolean[][] vis;public int numIslands(char[][] grid) {int m = grid.length;int n = grid[0].length;vis = new boolean[m][n];Queue<int[]> queue = new LinkedList<>();int ret = 0;//死循环while(true) {//找到第一个1,作为“登陆点”for(int i = 0; i < m; i++) {//标记break出循环boolean flag = false; for(int j = 0; j < n; j++) {if('1' == grid[i][j] && !vis[i][j]) {queue.add(new int[]{i,j});vis[i][j] = true;flag = true;break;}//所有vis元素都是true,返回if( (i == m - 1) &&(j == n - 1)) {return ret;}vis[i][j] = true;}if(flag) break;}//进行宽搜,找寻岛屿,并且修改岛屿值为0while(!queue.isEmpty()) {int[] arr = queue.poll();//向量法找寻周围1 入队列for(int i = 0; i < 4; i++) {int x = arr[0] + dx[i];int y = arr[1] + dy[i];//下标合法,字符数组元素为1,且并没有被访问,下标入队    if(x >= 0 && x < m && y >= 0 && y < n&& '1' == grid[x][y]&& !vis[x][y]) {vis[x][y] = true;queue.add(new int[]{x,y});}}} ret++;}}}

四、695. 岛屿的最⼤⾯积

题目链接:695. 岛屿的最⼤⾯积

题目描述:

题目解析:

  • 跟上一道题思路一样

解题思路:

  • 在上一道题中没出一个队列元素计算面积的值加一即可。

解题代码:

//时间复杂度:O(M*N)
//空间复杂度:O(M*N)
class Solution {int[] dx = {0,0,1,-1};int[] dy = {1,-1,0,0}; boolean[][] vis;public int maxAreaOfIsland(int[][] grid) {int m = grid.length;int n = grid[0].length;vis = new boolean[m][n];int ret = 0;Queue<int[]> queue = new LinkedList<>();while(true) {int size = 0;for(int i = 0; i < m; i++) {boolean flag = false;for(int j = 0; j < n; j++) {//登陆点if(1 == grid[i][j] && !vis[i][j]) {queue.add(new int[]{i,j});vis[i][j] = true;flag = true;System.out.println(i+" "+j+"如队列");break;}//结束条件if(i == m - 1 && j == n - 1) {System.out.println("结束条件 "+i+" "+j);if(grid[i][j] == 1 ) size++;return  Math.max(ret, size);}vis[i][j] = true;}if(flag) break;}//计算面积while(!queue.isEmpty()) {int[] arr = queue.poll();size++;int x = arr[0];int y = arr[1];//查看周边for(int i = 0; i <= 3; i++) {int a = x + dx[i];int b = y + dy[i];if(a >= 0 && a < m&& b >= 0 && b < n&& !vis[a][b]&& 1 == grid[a][b]) {queue.add(new int[]{a,b});vis[a][b] = true;}} }ret = Math.max(ret, size);}}
}

五、130.被围绕的区域

题目链接:130.被围绕的区域

题目描述:

题目解析:

  • 给我们一个字符数组,让我们将被完全由X字符包围的O改为X
  • 可以理解为只要字符数组边缘为O所在的岛屿留下,其它全变成X

解题思路:

  • 我们只需要遍历字符数组边缘元素,有O,那么就进行宽搜,将宽搜到的字符进行标记。
  • 我们引入一个与字符数组同等规模的标记数组,将能留下的O标记。
  • 最后在遍历一遍字符数组,将没有被标记的字符全改为X即可。
    解题代码:
//时间复杂度:O(M*N)
//空间复杂度:O(M*N)
class Solution {int[] dx = {0,0,1,-1};int[] dy = {1,-1,0,0};boolean[][] flag;int m,n;public void solve(char[][] board) {m = board.length;n = board[0].length;flag = new boolean[m][n];//只遍历边缘字符元素for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {if((i == 0|| i == m - 1|| j == 0|| j == n - 1) && 'O' == board[i][j] && !flag[i][j]) {bfs(board, i, j);}}}//将被包围的字符改为Xfor(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {if(board[i][j] == 'O' && !flag[i][j]) board[i][j] = 'X';}}}//宽搜符合条件的不被包围字符public void bfs(char[][] board, int x, int y) {Queue<int[]> queue = new LinkedList<>();queue.add(new int[]{x,y});flag[x][y] = true;while(!queue.isEmpty()) {int[] arr = queue.poll();for(int i = 0; i < 4; i++) {int a = dx[i] + arr[0];int b = dy[i] + arr[1];if(a >= 0 && a < m&& b >= 0 && b < n&&'O' == board[a][b] && !flag[a][b]) {queue.add(new int[]{a,b});flag[a][b] = true;}}}}
}
http://www.dtcms.com/a/391009.html

相关文章:

  • 量化交易 - Stochastic Gradient Descent Regression (SGDRegressor) 随机梯度下降回归 - 机器学习
  • AWS WAF防护IoT设备劫持攻击:智能设备安全防护实践
  • 分享mysql数据库自动备份脚本(本机和docker都可用)
  • avue crud表头跨列
  • 鸿蒙网络优化实战:从智能切换到缓存加速的完整指南
  • Redis-实现分布式锁
  • 软件工程实践五:Spring Boot 接口拦截与 API 监控、流量控制
  • 【LINUX网络】NAT _ 代理_ 内网穿透
  • 智慧养老+数字大健康:当科技为“银发时代”按下温暖加速键
  • rook-ceph的ssd类osd的纠删码rgw存储池在迁移时的异常处理
  • Http升级Https使用Certbot申请证书并免费续期
  • scTenifoldKnk:“虚拟敲除基因”,查看转录组其他基因的变化幅度(升高or降低)
  • 牛客算法基础noob47 校门外的树
  • AD-GS:稀疏视角 3D Gaussian Splatting 的“交替致密化”,同时抑制浮游物与保留细节
  • maven package多出来一个xxx.jar.original和一个xxx-shaded.jar是什么?怎么去掉
  • Gin 框架中使用 Validator 进行参数校验的完整指南
  • apt install nvidia-cuda-toolkit后cuda不在/usr/local/cuda怎么办
  • SpringBoot整合Kafka总结
  • Parasoft C/C++test 针对 CMake 项目的自动化测试配置
  • LED强光手电筒MCU控制方案开发分析
  • linux中为什么 rm 命令能删除自己 | linux使用rm命令删自己会怎样?
  • django登录注册案例(下)
  • 【TES600G】基于JFM7K325T FPGA+FT-M6678 DSP的全国产化信号处理平台
  • 卷积神经网络深度解析:从基础原理到实战应用的完整指南
  • 企业档案管理系统:精准破局制造行业档案管理困境
  • 【完整源码+数据集+部署教程】考古坑洞私挖盗洞图像分割系统: yolov8-seg-act
  • MMDB详解
  • TC8:SOMEIP_ETS_130测试用例解析
  • 等效学习率翻倍?梯度累积三连坑:未除以 accum_steps、调度器步进错位、梯度裁剪/正则标度错误(含可复现实验与修复模板)
  • 嵌入式学习笔记(44)IMX6ULL