leetcode934. 最短的桥(dfs+bfs)

118 阅读1分钟

在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)

现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。

返回必须翻转的 0 的最小数目。(可以保证答案至少是 1。)

示例 1:

输入:[[0,1],[1,0]]
输出:1

代码

class Solution {
    public void  helper(int[][] A,int[][] dir) {//dfs找出第一座岛,标为2

        for(int i=0;i<A.length;i++)
            for(int j=0;j<A[0].length;j++)
                if(A[i][j]==1)
                {
                    dfs(A,dir,i,j);
                    return;
                }
    }
    Queue<int[]> queue=new LinkedList<>();
    public int shortestBridge(int[][] A) {

        int[][] dir=new int[][]{{-1,0},{1,0},{0,1},{0,-1}};
        int n=A.length,m=A[0].length;
        helper(A,dir);

        while (!queue.isEmpty())//bfs
        {
            int[] e=queue.poll();
            int ex=e[0],ey=e[1],el=e[2];
            for(int[] d:dir)//向4个方向蔓延
            {
                int nextX=ex+d[0],nextY=ey+d[1];
                if(nextX<0||nextX>=A.length||nextY<0||nextY>=A[0].length||A[nextX][nextY]==2)
                    continue;//不能走的点
                if(A[nextX][nextY]==1) return el;
                queue.offer(new int[]{nextX,nextY,el+1});
                A[nextX][nextY]=2;//标记为第一座岛屿,避免重复访问
            }


        }
          return -1;
    }

    public void dfs(int[][] A,int[][] dir,int x,int y) {

        A[x][y]=2;
        queue.offer(new int[]{x,y,0});
        for(int[] d:dir)
        {
            int nextX=x+d[0],nextY=y+d[1];
            if(nextX<0||nextX>=A.length||nextY<0||nextY>=A[0].length||A[nextX][nextY]!=1)
                continue;
            dfs(A, dir, nextX, nextY);
        }

    }
}