BFS算法解决FloodFill问题

BFS算法解决FloodFill问题

图像渲染

题目解析 :就是将这里面指定一个元素将其上下左右和这个一样的值,全部修改成另外一个值,并且其上下左右也可以进行上下左右进行扩展,也就是将这个一片区域都修改成color指定值

BFS:直接遍历所有下标,并且看其上下左右下标,不断进行修改,不断进行扩展延申

此时就可以使用队列放入 int 数组,对应存放行、列下标,每一次不断取出进行上下左右延申判断其是否和imagesrsc,如果一样就继续放入队列中,不断进行操作,直到队列为空

这里通过上下左右对应下标分别

java 复制代码
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) {

        int prev = image[sr][sc];
        if(prev == color){
            //如果要修改和修改的一样,此时就不需要修改
            return image;
        }

        int m = image.length;
        int n = image[0].length;
        //存放其下标
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{sr,sc});

        while(!queue.isEmpty()){
            int[] tem = queue.poll();
            int a = tem[0];//行
            int b = tem[1];//列
            //将这个颜色修改
            image[a][b] = color;

            //看这个位置前后左右位置
            for(int i = 0;i < 4;i++){
                int x = a + dx[i];
                int y = b + dy[i];

                if(x >=0 && x < m && y>=0 && y < n && image[x][y] == prev){
                    queue.add(new int[]{x,y});
                }
            }
        }
        return image;
    }
}

岛屿数量

题目解析 :此时1表示岛屿,并且1的上下左右如果有1的话就会进行延申展开,最终求出有多少岛屿

BFS:遍历整个数组,但是此时一个岛屿需要延申到不能延申为止这样才成为一个岛屿 ,此时会出现问题,我们会不断扩展,后面遍历到这个位置又会让其岛屿数量+1,此时就重复统计了,这里有两种解决方案

方案一 :每次遍历过的位置,将这里的 1 修改成 0

方案二:创建一个同等规模的数组,如果统计过了就进行标记一下

java 复制代码
class Solution {
    int[] dx = {0,0,1,-1};
    int[] dy = {1,-1,0,0};
    boolean[][] visited;//标记已经遍历过的位置
    int m = 0;
    int n = 0;
    public int numIslands(char[][] grid) {
     m = grid.length;
        n = grid[0].length;
        visited = new boolean[m][n];
         int ret = 0;
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                //当时1并且没有遍历过,结果++
                if(grid[i][j] == '1' && visited[i][j] == false){
                    ret++;
                    dfs(grid,i,j);//将其旁边的visited都标记为遍历过
                }
            }
        }
         return ret;
    }
    public void dfs(char[][] grid,int i,int j){
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{i,j});
        visited[i][j] = false;
        while(!queue.isEmpty()){
            int[] tem = queue.poll();
            int a = tem[0];
            int b = tem[1];
            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&&grid[x][y] == '1' && !visited[x][y]){
                    queue.add(new int[]{x,y});
                    visited[x][y] = true;
                }
            }
        }
    }
   
}

岛屿的最大面积

题目解析 :就是找出岛屿最大面积

思想:此时和上一题岛屿数量类似,此时我们只需要在dfs方法中返回此时岛屿数量即可

java 复制代码
class Solution {
    int[] dx = { 0, 0, 1, -1 };
    int[] dy = { 1, -1, 0, 0 };
    boolean[][] visited;//标记已经遍历过的
    int m = 0;
    int n = 0;

    public int maxAreaOfIsland(int[][] grid) {
        int ret = 0;
        m = grid.length;
        n = grid[0].length;
        visited = new boolean[m][n];

        //此时遍历这个岛屿的时候统计一下它的面积,返回
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1 && visited[i][j] == false) {
                    //此时更新结果
                    ret = Math.max(ret, dfs(grid, i, j));
                }
            }
        }
        return ret;
    }

    public int dfs(int[][] grid,int i,int j){
        int count = 0;//此时岛屿面积
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{i,j});
        visited[i][j] = true;
       count++;
        while(!queue.isEmpty()){
           
            //队列为空就结束
            int[] tem = queue.poll();
            int a = tem[0];
            int b = tem[1];
            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 &&grid[x][y] == 1 && visited[x][y] == false){
                    queue.add(new int[]{x,y});

                   
                    visited[x][y] = true;
                     count++;
                }
            }
        }
        return count;
    }
}

被围住的区域

题目解析 :就是将被X围住的O修改成X,未被围住的不做修改

思想:由于以前是一边遍历,一边修,但是这里会出现不需要修改的问题,可能修改一半发现不需要修改,此时这里还需要进行二次判断因此这里采用正难则反的思想

1.先使用dfs遍历边界,此时将边界及其扩展部分修改成 其他字符

2.最后遍历一遍数组,将剩下未被修改的O修改成X,将这里被修改成其他字符的修改回以前的O字符

java 复制代码
class Solution {
    int[] dx = { 0, 0, 1, -1 };
    int[] dy = { 1, -1, 0, 0 };
    int m = 0;
    int n = 0;

    public void solve(char[][] board) {
        m = board.length;
        n = board[0].length;

        //1.将边界的O以及相邻的O全部修改成 . 最后在修改回来
        //左右两列
        for (int i = 0; i < m; i++) {
            if (board[i][0] == 'O') {
                dfs(board, i, 0);
            }
            if (board[i][n - 1] == 'O') {
                dfs(board, i, n - 1);
            }
        }
        //上下两行
        for (int i = 0; i < n; i++) {
            if (board[0][i] == 'O') {
                dfs(board, 0, i);
            }
            if (board[m - 1][i] == 'O') {
                dfs(board, m - 1, i);
            }
        }
        //剩下的O修改成X,将上面修改的还原
        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';
                }
            }
        }
    }

    public void dfs(char[][] board, int i, int j) {
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[] { i, j });
        board[i][j] = '.';//修改成.

        while (!queue.isEmpty()) {
            int[] tem = queue.poll();
            int a = tem[0];
            int b = tem[1];

            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 && board[x][y] == 'O') {
                    queue.add(new int[] { x, y });
                    board[x][y] = '.';

                }
            }
        }
    }
}
相关推荐
纪念 2291 小时前
C++算法(一)
开发语言·c++·算法
All for pursuit.1 小时前
【二叉树-10】114.二叉树展开为链表
数据结构·c++·算法·leetcode·链表
叠层归一研究院1 小时前
区分预算与通道诱导:Ω–L叠层体系的观测赋值与定量验证
人工智能·算法
BYSJMG2 小时前
计算机毕业设计选题推荐:基于大数据的快递物流运营数据分析与可视化,Spark与K-Means
大数据·算法·数据分析·spark·课程设计
阳明山水2 小时前
因果一致性正则化实战解析
人工智能·深度学习·算法·机器学习·架构
黄金龙PLUS3 小时前
5个1024比特大状态置换算法的设计与分析
算法·网络安全·密码学·哈希算法·同态加密
心中有你02144 小时前
C语言埃氏筛法(素数筛选)
c语言·数据结构·算法
Omics Pro5 小时前
Cell封面|衰老生物学开源AI工具包
数据库·人工智能·算法·机器学习·自然语言处理
UIU1147 小时前
递归算法与汉诺塔
c++·学习·算法·c#·递归