【BFS专题】— BFS解决FloodFill算法

1、  图像渲染 - 力扣(LeetCode)

思路:

  1. 代码:
    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) {
            //统计刚开始[sr,sc]坐标位置的颜色
            int prev = image[sr][sc];
            //处理便捷情况
            if(prev == color){
                return image;
            }
            int m = image.length;
            int n = image[0].length;
            Queue<int[]> q = new LinkedList<>();
            q.add(new int[]{sr, sc});
    
            //遍历队列
            while(!q.isEmpty()){
                int[] t = q.poll();
                int a = t[0];
                int b = t[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){
                        q.add(new int[]{x, y});
                    }
                }
            }
            return image;
        }
    }

 2、岛屿数量 - 力扣(LeetCode)

思路:

  1. 寻找相同的连通块,bfs算法,
  2. 可以找到1之后,就1修改成0,避免重复
  3. 也可以找到1之后将状态改成true
  4. 代码:
    class Solution {
        //创建全局变量
        int[] dx = {0, 0, 1, -1};
        int[] dy = {1, -1, 0, 0};
        //创建一个数组标记该位置下的状态
        boolean[][] vis;
        int m, n;
        public int numIslands(char[][] grid) {
            m = grid.length;
            n = grid[0].length;
            vis = new boolean[m][n];
            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] == false){
                        ret++;
                        bfs(grid, i, j);
                    }
                }
            }
            return ret;
        }
    
        public void bfs(char[][] grid, int i, int j){
            //先将这个位置加入到队列中
            Queue<int[]> q = new LinkedList<>();
            q.add(new int[]{i, j});
            vis[i][j] = true;
    
            //遍历上下左右四个方向
            while(!q.isEmpty()){
                int[] t = q.poll();
                int a = t[0], b = t[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 && grid[x][y] == '1' && vis[x][y] == false){
                        //添加到队列并且更新状态
                        q.add(new int[]{x,y});
                        vis[x][y] = true;
                    }
                }
            }
            
        }
    }

 3、岛屿的最大面积 - 力扣(LeetCode)

 

思路:

  1. 遇上一题的思路一样,只不过是加了一个count来统计最大面积的大小
  2. class Solution {
        int[] dx = {0, 0, 1, -1};
        int[] dy = {1, -1, 0, 0};
        boolean[][] vis;
        int n, m;
        public int maxAreaOfIsland(int[][] grid) {
            m = grid.length;
            n = grid[0].length;
            vis = new boolean[m][n];
            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 = Math.max(ret, bfs(grid, i, j));
                    }
                }
            }
            return ret;
        }
    
        public int bfs(int[][] g, int i, int j){
            int count = 0;
            Queue<int[]> q = new LinkedList<>();
            q.add(new int[]{i,j});
            //对传入的坐标的状态进行初始化
            vis[i][j] = true;
            count++;
            while(!q.isEmpty()){
                int[] t = q.poll();
                int a = t[0];
                int b = t[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 && g[x][y] == 1 && !vis[x][y]){
                        q.add(new int[]{x,y});
                        vis[x][y] = true;
                        count++;
                    }
                }
            }
            return count;
        }
    }

 4、被围绕的区域 - 力扣(LeetCode)

思路:

  1. 我们先用bfs将边界的O给修改成  点
  2. 然后再开始修改全部被包围的O
  3. 最后把点还原成 O
  4. 代码:
    class Solution {
        int[] dx = {0, 0, 1, -1};
        int[] dy = {1, -1, 0, 0};
        int m, n;
        public void solve(char[][] board) {
            m = board.length;
            n = board[0].length;
    
            //1、先处理边界情况,把边界的O全改成 .
            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 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);
                }
            }
    
            //2、还原 O
            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 bfs(char[][] b, int i, int j){
            Queue<int[]> q = new LinkedList<>();
            q.offer(new int[] {i,j});
            b[i][j] = '.';
    
            while(!q.isEmpty()){
                int[] t = q.poll();
                int a = t[0];
                int b1 = t[1];
                for(int k = 0; k < 4; k++){
                    int x = a + dx[k];
                    int y = b1 + dy[k];
                    if(x >= 0 && x < m && y >= 0 && y < n && b[x][y] == 'O'){
                        b[x][y] = '.';
                        q.offer(new int[] {x, y});
                    }
                }
            }
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值