算法题目---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';
                }
            }
        }
    }
}
相关推荐
风筝在晴天搁浅9 小时前
LeetCode CodeTop 82.删除排序链表中的重复元素Ⅱ
算法·leetcode·链表
189228048619 小时前
NV114固态MT29F16T08EWLEHD6-MES:E
人工智能·算法·缓存·性能优化
Tairitsu_H9 小时前
[LC优选算法#4] 滑动窗口 | 串联所有单词的⼦串 | 最⼩覆盖⼦串
c++·算法·滑动窗口
devilnumber9 小时前
Java 二分查找(二分算法)详解 + 实战运用 + 核心坑点
java·开发语言·算法
洛水水9 小时前
【力扣100题】84.字符串解码
算法·leetcode·职场和发展
MicroTech202510 小时前
量子隐形传态路线的瓶颈与突破,微算法科技(MLGO)以技术创新助力量子通信长距离组网
科技·算法·量子计算
洛水水10 小时前
【力扣100题】89.下一个排列
数据结构·算法·leetcode
洛水水10 小时前
【力扣100题】90.寻找重复数
算法·leetcode·职场和发展
鱼子星_10 小时前
【数据结构】排序的拓展——快速排序的生态多样性与归并排序沾染文件操作
c语言·数据结构·算法
alphaTao10 小时前
LeetCode 每日一题 2026/6/8-2026/6/14
算法·leetcode