算法BFS经典例题(迷宫,多源BFS,BFS解决拓扑排序,FloodFill算法)

简介: 算法BFS经典例题(迷宫,多源BFS,BFS解决拓扑排序,FloodFill算法)

int[2][3]

力扣733.图像渲染

FloodFill算法

洪水灌溉

广度优先遍历的本质就是暴力遍历  把所有的结果都走一遍(具体说怎么走的方向没有谈及,说是二叉树遍历,但是实际上也就是一层全部走完,并没有什么特定的规律说是往哪里走完)

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;
        //m是横着的下标和,n是竖着的下标和
        int m=image.length,n=image[0].length;
 
        Queue<int[]>q=new LinkedList<>();
        //把初始两个下标放到了数组里面,然后队列add的是这个数组
        q.add(new int[]{sr,sc});
 
        while(!q.isEmpty()){
            //取出队列的开头
            int []t=q.poll;
            //a,b表示的是取出来的下标
            int a=t[0],b=t[1];
            image[a][b]=color;
            //为什么是小于4因为对应的是4个方向
            for(int i=0;i<4;i++){
                int x=a+dx[i],y=b+dy[i];
                //看他越不越界,并且看他是否和目标元素相同,而且因为我们是边遍历,边去修改,所以最开始的值是发生变化了,所以不回再次进入循环
                if(x>=0&&x<m&&y<n&&image[x][y]==prev){
                    //把符合要求数值下标加入队列里面,然后
                    q.add(new int[]{x,y});
                }
            }
        }
   return image;
 
    }
}

力扣200.岛屿数量


1.直接修改原数组

2.vis[m][n]实施标记,在原先的数组情况下,给予一层标记,遍历过的使用true;

这里比较难的地方是他的代码编写,思想其实挺好理解,存下标,用一个队列存储,然后看是不是你要的(唯一比较难的根据题意,上一道题是找相同的数,这个题意很清晰,但是这道题是要找所谓的“岛屿”,这也需要你理解这个所谓的岛屿什么的究竟是什么意思,这道题,他的岛屿的含义就是把周围的一圈是陆地的都标记了,假如说周围是水,那么不耽误,假如周围不是全是水,那么把他上下左右标记一圈,到达下一个然后看扫描你的上下左右,看你的上下左右有没有也是岛屿的,假如遇到标记的就跳过。

生活思维:岛屿是被水包围的,总想是围棋一样,我们未培养起来编程思维,就感觉不知道从何下手

但是编程思维,就是先把一圈走了,看看上下左右的分布,是陆地的标记,他能把从第一个开始到不是这块的,都统计为一个,然后是水的就不标记,直接跳过,直到再找到一块岛屿,在遍历他的周围,周围没有的话,就再加一以此反复。

class Solution {
   int[]dx={0,0,1,-1};
     int[]dy={1,-1,0,0};
    boolean[][] vis=new boolean[301][301];
    int m,n;
    public int numIslands(char[][] grid) {
         m=grid.length;
         n=grid[0].length;
        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){
        //在q里和那个图像渲染一样,在q里加入初始位置的下标
        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;  
               }
           } 
       }
    }
}

力扣695岛屿最大面积

class Solution {
    int[]dx={0,0,1,-1};
    int[]dy={1,-1,0,0};
    int sum=0;
    int m,n;
    boolean[][]vis=new boolean[51][51];
    public int maxAreaOfIsland(int[][] grid) {
    m=grid.length;
    n=grid[0].length;
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
         if(grid[i][j]==1&&vis[i][j]==false)
          sum=Math.max(sum,bfs(grid,i,j));
        }
    }
return sum;
    }
    public int bfs(int[][]grid,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&&vis[x][y]==false&&grid[x][y]==1){        q.add(new int[]{x,y});
             count++;
             vis[x][y]=true;
         }
    }
 }
 return count;
    }
 
}

力扣130.被围绕的区域(微难)

恶补二维数组知识

为神马说他微难呢?是因为当我们想用套模版莽夫做这个题,会发现一个问题,就是他怎么判断是否被包围,我们之前的都是边判断边修改,这个需要你看一圈之后,才判断是否需要修改。

解法:正难则反:先去把周围都给处理改成一个点,不影响判断的,只要把四边相邻的处理(这些事不被包围的)然后再去扫描矩阵,然后再去恢复成O

注意:小细节,这道题不需要统计xx数量,所以不需要我们搞一个boolean去标记

此外,这个题的正难则反,是bfs也去用来扫描矩阵,而中间的都是被包围的,所以不需要做处理,只需要都遍历的时候,把中间的一圈改成x,因为未被包围的我们都改成.了,所以不会影响我们操作,最后把.换回X即可

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;
        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);
         }
     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[][]board,int i,int j){
        Queue<int[]>q=new LinkedList<>();
        q.add(new int[]{i,j});
        board[i][j]='.';
        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-1&&y>0&&y<n-1&&board[x][y]=='O'){
                 q.add(new int[]{x,y});
                 board[x][y]='.';  
             }
         }   
        }
    }
}


相关文章
|
9天前
|
存储 机器学习/深度学习 算法
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
16 3
|
12天前
|
算法 C语言
【数据结构与算法 经典例题】使用栈实现队列(图文详解)
【数据结构与算法 经典例题】使用栈实现队列(图文详解)
|
12天前
|
算法 C语言
【数据结构与算法 经典例题】使用队列实现栈(图文详解)
【数据结构与算法 经典例题】使用队列实现栈(图文详解)
|
11天前
|
算法 Java 调度
Java数据结构与算法:拓扑排序
Java数据结构与算法:拓扑排序
|
11天前
|
算法 搜索推荐 C++
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
15 0
|
12天前
|
算法 C语言 计算机视觉
【数据结构与算法 经典例题】括号匹配问题
【数据结构与算法 经典例题】括号匹配问题
|
12天前
|
算法
【数据结构与算法 经典例题】随机链表的复制(图文详解)
【数据结构与算法 经典例题】随机链表的复制(图文详解)
|
12天前
|
算法 C语言
【数据结构与算法 经典例题】链表的回文结构(图文详解)
【数据结构与算法 经典例题】链表的回文结构(图文详解)
|
12天前
|
算法
【数据结构与算法 经典例题】反转链表(图文详解)
【数据结构与算法 经典例题】反转链表(图文详解)