首页 > 编程语言 >BFS 算法专题(二):BFS 解决 FloodFill 算法

BFS 算法专题(二):BFS 解决 FloodFill 算法

时间:2024-11-13 17:15:55浏览次数:3  
标签:int FloodFill BFS 算法 grid board && new check

目录

1. 图像渲染

1.1 算法原理

1.2 算法代码

2. 岛屿数量

2.1 算法原理

2.2 算法代码

3. 岛屿的最大面积

3.1 算法原理

3.2 算法代码

4. 被围绕的区域

4.1 算法原理

4.2 算法代码


1. 图像渲染

. - 力扣(LeetCode)

1.1 算法原理

在本专题之前, 对于 FloodFill 算法, 我们就已经使用 DFS 的形式求解过了. 

BFS 与 DFS 解题的核心思想是相同的, 都是找到 性质相同的连通块.

但 BFS 与 DFS 不同的是:

  1. DFS 是一条路走到黑, 一旦发现某个方向上可以走, 就一直沿着那个方向往下走, 等到不能再走时才会回头. (深搜递归)
  2. BFS 是一层一层的剥开, 把当前节点位置上的所有方向都看一遍, 记录满足条件的位置, 才往下一个位置上走 (宽搜队列)

1.2 算法代码

class Solution {
    int oldColor;
    int[] dx = new int[]{-1, 1, 0, 0};
    int[] dy = new int[]{0, 0, -1, 1};
    public int[][] floodFill(int[][] image, int sr, int sc, int color) {
        if(image[sr][sc] == color) return image;
        int m = image.length, n = image[0].length;
        oldColor = image[sr][sc];
        Queue<int[]> q = new LinkedList<>();
        q.offer(new int[]{sr, sc});
        while(!q.isEmpty()) {
            int[] arr = q.poll();
            int a = arr[0], b = arr[1];
            image[a][b] = color;
            for(int k = 0; k < 4; k++) {
                int x = a + dx[k];
                int y = b + dy[k];
                if(x >= 0 && x < m && y >= 0 && y < n && image[x][y] == oldColor) {
                    q.offer(new int[]{x, y});
                } 
            }
        }
        return image;
    }
}

2. 岛屿数量

. - 力扣(LeetCode)

2.1 算法原理

本题依旧采用 BFS 的思想, 需要注意的是, 不能重复访问同一个位置.

避免相同位置的重复访问, 有以下两种方式避免:

  1. 访问完后, 修改原来的值(会导致原数组中的值被改变)
  2. 设置布尔类型的变量, 访问完后, 标记一下(采用)

2.2 算法代码

class Solution {
    int[] dx = {1, -1, 0, 0};
    int[] dy = {0, 0, 1, -1};
    boolean[][] check;
    int m, n;
    int ret;
    public int numIslands(char[][] grid) {
        m = grid.length;
        n = grid[0].length;
        check = new boolean[m][n];
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(grid[i][j] == '1' && !check[i][j]) {
                    ret++;
                    bfs(grid, i, j);
                }
            }
        }
        return ret;
    }
    public void bfs(char[][] grid, int i, int j) {
        Queue<int[]> q = new LinkedList<>();
        q.offer(new int[]{i, j});
        check[i][j] = true;
        while(!q.isEmpty()) {
            int[] tmp = q.poll();
            int a = tmp[0], b = tmp[1];
            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 && !check[x][y] && grid[x][y] == '1') {
                    q.offer(new int[]{x, y});
                    check[x][y] = true;
                }
            }
        }
    }
}

3. 岛屿的最大面积

. - 力扣(LeetCode)

3.1 算法原理

解题思路与上题相同, 只需使用变量额外的记录一下岛屿的面积即可.

返回所有岛屿中最大的面积.

3.2 算法代码

class Solution {
    int[] dx = {0, 0, 1, -1};
    int[] dy = {1, -1, 0, 0};
    boolean[][] check;
    int m, n;
    int ret;
    public int maxAreaOfIsland(int[][] grid) {
        m = grid.length; n = grid[0].length;
        check = new boolean[m][n];
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(grid[i][j] == 1 && !check[i][j]) {
                    ret = Math.max(bfs(grid, i, j), ret);
                }
            }
        }
        return ret;
    }
    public int bfs(int[][] grid, int i, int j) {
        int count = 1;
        Queue<int[]> q = new LinkedList<>();
        q.offer(new int[]{i, j});
        check[i][j] = true;
        while(!q.isEmpty()) {
            int[] tmp = q.poll();
            int a = tmp[0], b = tmp[1];
            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 && !check[x][y] && grid[x][y] == 1) {
                    count++;
                    check[x][y] = true;
                    q.offer(new int[]{x, y});
                }
            }
        }
        return count;
    }
}

4. 被围绕的区域

. - 力扣(LeetCode)

4.1 算法原理

核心: 正难则反

  1. 使用布尔变量, 标记边界情况下的 'O'.
  2. 将非标记的字符全部修改为 'X' 

4.2 算法代码

class Solution {
    // 正难则反
    int m, n;
    boolean[][] check;
    int[] dx = {1, -1, 0, 0};
    int[] dy = {0, 0, 1, -1};
    public void solve(char[][] board) {
        m = board.length; n = board[0].length;
        check = new boolean[m][n];
        // 处理边界上的 'O'
        for(int i = 0; i < m; i++) {
            if(board[i][0] == 'O' && !check[i][0]) bfs(board, i, 0);
            if(board[i][n - 1] == 'O' && !check[i][n - 1]) bfs(board, i, n - 1);
        }
        for(int j = 0; j < n; j++) {
            if(board[0][j] == 'O' && !check[0][j]) bfs(board, 0, j);
            if(board[m - 1][j] == 'O' && !check[m - 1][j]) bfs(board, m - 1, j);
        }
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(!check[i][j]) board[i][j] = 'X';
            }
        }
    }
    public void bfs(char[][] board, int i, int j) {
        Queue<int[]> q = new LinkedList<>();
        q.offer(new int[]{i, j});
        check[i][j] = true;
        while(!q.isEmpty()) {
            int[] tmp = q.poll();
            int a = tmp[0], b = tmp[1];
            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' && !check[x][y]) {
                    check[x][y] = true;
                    q.offer(new int[]{x, y});
                }
            }
        }
    }
}

END

标签:int,FloodFill,BFS,算法,grid,board,&&,new,check
From: https://blog.csdn.net/2401_83595513/article/details/143573723

相关文章

  • 代码随想录算法训练营第二十五天| leetcode491.递增子序列、leetcode46.全排列、leetc
    1leetcode491.递增子序列题目链接:491.非递减子序列-力扣(LeetCode)文章链接:代码随想录视频链接:回溯算法精讲,树层去重与树枝去重|LeetCode:491.递增子序列_哔哩哔哩_bilibili思路:用之前的方法,结果翻车了,好好看视频学新技能吧1.1视频后的思路真的没想到用set来去重,还是基......
  • 迪杰斯特拉算法、弗洛伊德算法和BFS(广度优先搜索)
    迪杰斯特拉算法、弗洛伊德算法和BFS(广度优先搜索)都是用于求解最短路径问题的经典算法,它们各自有不同的特点和适用场景。以下是对这三种算法的介绍、区别以及代码实现的简要概述。迪杰斯特拉算法(Dijkstra'salgorithm)介绍:迪杰斯特拉算法是一种单源最短路径算法,用于计算一个......
  • 代码随想录算法训练营 | 所有可达路径
    所有可达路径文章链接:https://programmercarl.com/kamacoder/0098.所有可达路径.html#本题代码题目链接:https://kamacoder.com/problempage.php?pid=1170#include<iostream>#include<vector>usingnamespacestd;//全局路径vector<vector<int>>paths;vector<in......
  • c语言第九课,各种算法
    选择排序选择排序(从未排序列找到最值,放到排序序列的起始位置)#include<stdio.h>voidselect_sort(inta[],intn)//定义选择排序函数{  for(inti=0;i<n-1;i++)//遍历数组找到最小的元素索引,n-1是因为最后一次可以排序两个  {    intmin=i;//假......
  • 洛谷题单 算法2-2 常见优化技巧
    洛谷题单算法2-2常见优化技巧单调栈单调栈最经典的应用,就是在一个数列里寻找距离元素最近的比其大/小的元素位置。模板题,寻找每个元素右边第一个比它大的元素下标。stack<int>s;for(inti=n;i>=1;i--){while(s.size()&&a[s.top()]<=a[i])s.pop();f[i]=s.......
  • 非煤矿山算法智慧矿山一体机提升机危险区域违规闯入识别边坡监测预警系统详述
    在矿山行业中,安全始终是最为关键的议题。随着智能化技术的发展,智慧矿山一体机应运而生,它专为矿山安全监控和管理设计,集成了多种智能化功能,以提升矿山的安全监管能力和生产效率。这款设备不仅能够满足矿山场景下的视频智能化建设需求,还能够通过边缘计算技术实现对矿山安全风险的实......
  • 【算法学习】单调队列优化dp
    前言这已经是很基础很模板化的优化了,我们可以理解为用贪心的思路去掉了永远不可能用到的状态,通常用于长度固定是个区间、最大值且满足单调性的题目。如果一个选手比你小,还比你强,你就永远也打不过他了。这很残酷但这也是单调队列的思想,虽然现实情况比较多变。P3572[POI2014]PT......
  • 街面环卫算法视频分析服务器沿街晾晒智慧城管算法详解
    在城市精细化管理的背景下,智慧城管和街面秩序维护的需求日益增长。为了提高城市管理效率,确保城市秩序和市容市貌,一款集高清视频监控、智能分析与告警、数据资源共享服务于一体的智能化一体机设备应运而生。本文将详细介绍街面环卫算法视频分析服务器的功能特点以及其在智慧城管和......
  • 视频智能分析网关视频分析网关工服检测算法:提升安全监管效率的关键技术
    随着AI技术的持续发展,智能视频分析网关已经成为多个行业安全监控的关键设备。在这些网关中,工服检测算法作为一项关键技术,利用深度学习和计算机视觉技术,能够实时监控并分析监控视频中工作人员的工服穿着情况。本文将详细分析视频智能分析网关视频分析网关的工服检测算法,并探讨其在......
  • 烟火检测视频分析网关算法网关智慧工厂安全生产视频监管方案
    在数字化时代,企业转型升级已成为实现可持续发展的必由之路。特别是在工业领域,工厂的智能化转型不仅能够提高生产效率,还能加强安全管理,确保员工的健康与安全。TSINGSEE青犀AI智能分析网关V4与安防监控视频管理系统EasyCVR视频融合平台的结合,为工厂提供了一个实现智能化转型、构建智......