算法题目---BFS解决FloodFill算法问题

(一).基础概念

FloodFill算法,也称为"洪水灌溉"算法。通过一个图来看

此时,方框表示一个区域,其中里面的负数表示这个部分是往下凹的,正数部分是往上凸的。如果此时发洪水了,那么首先,会将凹的部分填平

此时,就会出现上图的结果。然后就会问,有多少部分被填平,或者是被填平的最大部分是多少。

事实上,就是在找"性质相同的连通块"

解决方法有两种:①.dfs ②.bfs

dfs,深度优先遍历,采用递归的方式,一条路走到黑,直到走不了的时候就返回

bfs,广度优先遍历,也称为层序遍历,一层一层的遍历

对于广度优先遍历,不同的题目有不同的要求。有些题目是找某个点的上下左右四个方向,有些题目会找某个点的上下左右,左上,左下,右上,右下 ,八个方向

(二).具体题目

1.图像渲染

733. 图像渲染 - 力扣(LeetCode)

解法:bfs

java 复制代码
class Solution {
    public int[] dx={0,0,1,-1};
    public 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){    //处理边界情况,如果prev调整之前的颜色和color调整之后的颜色一样,则不需要调整
            return image;
        }
        int lenR=image.length;
        int lenC=image[0].length;

        Queue<int[]> queue=new ArrayDeque<>();   //里面存数组的原因是,保存下标
        queue.add(new int[]{sr,sc});
        while (!queue.isEmpty()){
            int[] poll=queue.poll();
            int x=poll[0];
            int y=poll[1];
            image[x][y]=color;
            //找上下左右四个方向的值
            for (int i = 0; i < 4; i++) {
                int newX=x+dx[i];
                int newY=y+dy[i];
                if (newX>=0 && newX<lenR && newY>=0 && newY<lenC && image[newX][newY]==prev){
                    queue.add(new int[]{newX,newY});
                }
            }
        }
        return image;
    }
}

2.岛屿数量

200. 岛屿数量 - 力扣(LeetCode)

解法:bfs

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

    boolean[][] visit;//标记数组,用于标记已经遍历过的位置
    public int numIslands(char[][] grid) {
        int ret=0;
        int rowLength=grid.length;
        int colLength=grid[0].length;
        visit=new boolean[rowLength][colLength];
        for (int i = 0; i < rowLength; i++) {
            for (int j = 0; j < colLength; j++) {
                if (grid[i][j]=='1' && visit[i][j]==false){
                    ret++;
                    bfs(grid,i,j);
                }
            }
        }
        return ret;
    }

    private void bfs(char[][] grid, int x, int y) {
        Queue<int[]> queue=new ArrayDeque<>();
        queue.add(new int[]{x,y});
        visit[x][y]=true;
        while (!queue.isEmpty()){
            int[] poll = queue.poll();
            int posx=poll[0];
            int poxy=poll[1];
            for (int i = 0; i < 4; i++) {
                int newX=posx+dx[i];
                int newY=poxy+dy[i];
                if (newX>=0 && newX<grid.length && newY>=0 && newY<grid[0].length && grid[newX][newY]=='1' && visit[newX][newY]==false){
                    queue.add(new int[]{newX,newY});
                    visit[newX][newY]=true;
                }
            }
        }
    }
}

3.岛屿的最大面积

695. 岛屿的最大面积 - 力扣(LeetCode)

解法:bfs

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

    boolean[][] visit;

    public int maxAreaOfIsland(int[][] grid) {
        int max=Integer.MIN_VALUE;
        int rowLength=grid.length;
        int colLength=grid[0].length;
        visit=new boolean[rowLength][colLength];
        for (int i = 0; i < rowLength; i++) {
            for (int j = 0; j < colLength; j++) {
                if (grid[i][j]==1 && visit[i][j]==false){
                    max=Math.max(max,bfs(grid,i,j));
                }
            }
        }
        return max==Integer.MIN_VALUE?0:max;
    }

    private int bfs(int[][] grid, int x, int y) {
        Queue<int[]> queue=new ArrayDeque<>();
        queue.add(new int[]{x,y});
        visit[x][y]=true;
        int count=1;
        while (!queue.isEmpty()){
            int[] poll = queue.poll();
            int posx=poll[0];
            int posy=poll[1];
            for (int i = 0; i < 4; i++) {
                int newX=posx+dx[i];
                int newY=posy+dy[i];
                if (newX>=0 && newX<grid.length && newY>=0 && newY<grid[0].length && grid[newX][newY]==1 && visit[newX][newY]==false){
                    queue.add(new int[]{newX,newY});
                    visit[newX][newY]=true;
                    count++;
                }
            }
        }
        return count;
    }
}

4.被围绕的区域

130. 被围绕的区域 - 力扣(LeetCode)

解法:正难则反

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

    public void solve(char[][] board) {
        int lenR=board.length;
        int lenC=board[0].length;

        for (int i = 0; i < lenC; i++) {  
            if (board[0][i]=='O'){      //遍历第0行
                board[0][i]='1';
                bfs(board,0,i);
            }
            if (board[lenR-1][i]=='O'){   //遍历最后一行
                board[lenR-1][i]='1';
                bfs(board,lenR-1,i);
            }
        }

        for (int i = 0; i < lenR; i++) {   
            if (board[i][0]=='O'){    //遍历第0列
                board[i][0]='1';
                bfs(board,i,0);
            }

            if (board[i][lenC-1]=='O'){   //遍历最后一列
                board[i][lenC-1]='1';
                bfs(board,i,lenC-1);
            }
        }
        
        //还原
        for (int i = 0; i < lenR; i++) {
            for (int j = 0; j < lenC; j++) {
                if (board[i][j]=='O'){
                    board[i][j]='X';
                }
                if (board[i][j]=='1'){
                    board[i][j]='O';
                }
            }
        }
    }

    private void bfs(char[][] board, int x, int y) {
        Queue<int[]> queue=new ArrayDeque<>();
        queue.add(new int[]{x,y});
        board[x][y]='1';
        while (!queue.isEmpty()){
            int[] poll = queue.poll();
            int posX=poll[0];
            int posY=poll[1];
            for (int i = 0; i < 4; i++) {
                int newX=posX+dx[i];
                int newY=posY+dy[i];
                if (newX>=0 && newX<board.length && newY>=0 && newY<board[0].length && board[newX][newY]=='O'){
                    queue.add(new int[]{newX,newY});
                    board[newX][newY]='1';
                }
            }
        }
    }
}
相关推荐
高晶40 分钟前
无乘法器实现LC二阶滤波器:基于移位运算的快速算法与四种精度推导
算法·设计模式·程序员
ysbfsy44 分钟前
大数计算思路
算法
高晶1 小时前
主从自动分配算法:平均值乘以设备数一半的选举基准值解析
算法·设计模式·程序员
学电子她就能回来吗1 小时前
LeetCode Hot 100|普通数组专题学习笔记(零基础版)
笔记·算法·leetcode
用户老李1 小时前
反向传播计算梯度举例
算法
niyongsheng1 小时前
多智能体连续时间内路径规划:AA-SIPP(m) 的 Rust 实现与算法
算法·rust·机器人
302wanger2 小时前
DeepSeek-V4.1-Flash-1017 免费用到1024,速来
算法
lisw053 小时前
微分与积分的本质区别解析
算法·数学建模·极限编程
xys_6783 小时前
深挖数据结构:树和二叉树(上)
数据结构·算法
Interview Aid1124 小时前
Google SWE Intern VO 面经:两轮 Coding,Follow-up 考察 BFS 状态
算法