算法题目---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';
                }
            }
        }
    }
}
相关推荐
kiracrimson几秒前
希尔排序:让插入排序不再怕逆序
数据结构·算法·排序算法
yi01144 分钟前
DAY17: LeetCode 139|单词拆分:从“把单词删掉”到用 DP 记录合法切口
人工智能·笔记·python·算法·leetcode·动态规划
陈希瑞1 小时前
LongCat-2.5-Preview 的web逆向能力实测
人工智能·算法·wasm
tangguofeng2 小时前
基于分治策略的循环赛日程表问题的思路讲解
算法
起个名字费劲死了3 小时前
VisionMaster集成深度学习算法(基础狗)
人工智能·深度学习·算法
lengxuenong3 小时前
枚举例题分析
c++·算法·青少年编程
Navigator_Z3 小时前
LeetCode //C - 1269. Number of Ways to Stay in the Same Place After Some Steps
c语言·算法·leetcode
2601_965742223 小时前
短视频脚本创作方法分享:本地生活类账号的起步思路
大数据·人工智能·算法·ai·新媒体运营·生活
55873生态系统手记3 小时前
读完 55873 资产钱包的技术栈,我重新理解了 "合规钱包" 应该长什么样
算法·架构
旋生万物3 小时前
素数螺旋映射 $z_n=n^{1+i}$ 的角分布统计检验与零模型对比
大数据·前端·人工智能·算法·云原生·螺旋生成论·螺旋相位