【LeetCode】Day167-最短的桥

题目

934. 最短的桥【中等】

题解

这道真的是中等题吗。。。

BFS

思路
利用 BFS 找到矩阵中两个块的最短距离。首先找到一座岛,然后向周围一圈延伸,直到找到另一座岛,这个“圈数”即为最短距离。

算法

  • 遍历找到grid中的1,然后进行BFS,此时可以得到第一座岛island的位置,将其全部标记为-1
  • 从island中所有位置开始进行BFS,到达任意1,说明到达了另一座岛,搜索层数即为答案
class Solution {
    public int shortestBridge(int[][] grid) {
         int n=grid.length;
         List<int[]>island=new ArrayList<>();
         Queue<int[]>queue=new LinkedList<>();
         int[][] dirs={{-1,0},{1,0},{0,1},{0,-1}};
         for(int i=0;i<n;i++){
             for(int j=0;j<n;j++){
                 //遇岛
                 if(grid[i][j]==1){
                     queue.offer(new int[]{i,j});
                     grid[i][j]=-1;
                     while(!queue.isEmpty()){
                         int[] cell=queue.poll();
                         int x=cell[0],y=cell[1];
                         island.add(cell);
                         //对第一座岛进行bfs
                        for(int k=0;k<4;k++){
                            int nx=x+dirs[k][0];
                            int ny=y+dirs[k][1];
                            if(nx>=0&&nx<n&&ny>=0&&ny<n&&grid[nx][ny]==1){
                                queue.offer(new int[]{nx,ny});
                                grid[nx][ny]=-1;
                            }
                        }
                     }
                    for(int[] cell:island)
                        queue.offer(cell);
                        
                    //找第二座岛
                    int step=0;
                    while(!queue.isEmpty()){
                        int sz=queue.size();
                        //遍历第一座岛周围每一圈位置
                        for(int d=0;d<sz;d++){
                            int[] cell=queue.poll();
                            int x=cell[0],y=cell[1];
                            //bfs
                            for(int k=0;k<4;k++){
                                int nx=x+dirs[k][0];
                                int ny=y+dirs[k][1];
                                if(nx>=0&&ny>=0&&nx<n&&ny<n){
                                    if(grid[nx][ny]==0){
                                        queue.offer(new int[]{nx,ny});
                                        grid[nx][ny]=-1;
                                    }
                                    //发现岛屿!返回圈数
                                    else if(grid[nx][ny]==1)
                                        return step;
                                }
                            }
                        }
                        step++;
                    }
                }
            }
        }
        return 0;
    }
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( n 2 ) O(n^2) O(n2)

DFS+BFS

用 DFS 遍历第一座岛,再用 BFS 寻找第二座岛

class Solution {
    int n;
    public int shortestBridge(int[][] grid) {
        n=grid.length;
        int[][] dirs={{-1,0},{1,0},{0,1},{0,-1}};
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                //遇岛
                if(grid[i][j]==1){
                    //遍历第一座岛
                    Queue<int[]>queue=new LinkedList<>();
                    dfs(i,j,grid,queue);
                        
                    //找第二座岛
                    int step=0;
                    while(!queue.isEmpty()){
                        int sz=queue.size();
                        //遍历第一座岛周围每一圈位置
                        for(int d=0;d<sz;d++){
                            int[] cell=queue.poll();
                            int x=cell[0],y=cell[1];
                            //bfs
                            for(int k=0;k<4;k++){
                                int nx=x+dirs[k][0];
                                int ny=y+dirs[k][1];
                                if(nx>=0&&ny>=0&&nx<n&&ny<n){
                                    if(grid[nx][ny]==0){
                                        queue.offer(new int[]{nx,ny});
                                        grid[nx][ny]=-1;
                                    }
                                    //发现岛屿!返回圈数
                                    else if(grid[nx][ny]==1)
                                        return step;
                                }
                            }
                        }
                        step++;
                    }
                }
            }
        }
        return 0;
    }
    public void dfs(int x,int y,int[][] grid,Queue<int[]>queue){
        if(x<0||y<0||x>=n||y>=n||grid[x][y]!=1)
            return;
        queue.offer(new int[]{x,y});
        grid[x][y]=-1;
        dfs(x+1,y,grid,queue);
        dfs(x-1,y,grid,queue);
        dfs(x,y+1,grid,queue);
        dfs(x,y-1,grid,queue);
    }
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( n 2 ) O(n^2) O(n2)

ps 图的遍历老不写真的忘干净了呀…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值