力扣:934. 最短的桥

295 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第33天,点击查看活动详情

力扣——934. 最短的桥

934. 最短的桥 - 力扣(LeetCode)

给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域。

是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连。grid恰好存在两座岛

你可以将任意数量的 0 变为 1 ,以使两座岛连接起来,变成 一座岛

返回必须翻转的 0 的最小数目。

示例 1:

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

示例 2:

输入:grid = [[0,1,0],[0,0,0],[0,0,1]]
输出:2

示例 3:

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

提示:

  • n == grid.length == grid[i].length
  • 2 <= n <= 100
  • grid[i][j]01
  • grid 中恰有两个岛

问题解析

因为grid恰好有两个岛,初始两个岛的值都是1,为了方便我们可以先把其中一个岛通过bfs给染成另一个数(我这里染成的是2)。顺便记录下这个岛上的一个位置的坐标(x,y)。

我们可以以(x,y)为起点进行bfs,来判断从其中一个岛走到另一个岛的最短距离。

bfs过程中维护三个值x,y,z:当前位置的下标(x,y)、在grid为0的地方连续走了z格。

为了防止走出,用一个三维数组st来给每个格子打上标记,st[x] [y] [z]表示走到(x,y)位置时,是否已经在grid为0的地方连续走了z格,如果为true,我们就不用再从这里进行bfs了。

因为我们是从自己染色的岛出发,所以当bfs到颜色为1的地方时,z就是我们桥的长度,但是这不一定是最优解,所以我们还要继续bfs,直到所有桥都搭好后选取最短的那个。

AC代码

class Solution {
public:
    int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1},n,m;
    void bfs(int x,int y,int color,vector<vector<int>>&grid)
    {
        grid[x][y]=color;
        vector<vector<int>>st(n,vector<int>(m,0));
        queue<pair<int,int>>que;
        que.push({x,y});
        st[x][y]=1;
        while(!que.empty())
        {
            int len=que.size();
            for(int i=0;i<len;i++)
            {
                x=que.front().first,y=que.front().second;
                que.pop();
                for(int j=0;j<4;j++)
                {
                    int a=x+dx[j],b=y+dy[j];
                    if(a>=0&&a<n&&b>=0&&b<m&&!st[a][b]&&grid[a][b]==1)
                    {
                        grid[a][b]=color;
                        st[a][b]=1;
                        que.push({a,b});
                    }
                }
            }
        }
    }
    int shortestBridge(vector<vector<int>>& grid) {
        n=grid.size(),m=grid[0].size();
        int cnt=2,x=-1,y=-1;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                
                if(grid[i][j]==1)
                {
                    if(x==-1)
                    {
                        x=i,y=j;
                    }
                    bfs(i,j,cnt++,grid);
                }
            }
        }
        vector<vector<int>>st(n,vector<int>(m,0)),ans(n,vector<int>(m,100000));
        queue<pair<int,pair<int,int>>>que;
        que.push({0,{x,y}});
        st[x][y]=1;
        int mn=1e9;
        while(!que.empty())
        {
            int len=que.size();
            for(int i=0;i<len;i++)
            {
                x=que.front().second.first,y=que.front().second.second;
                for(int j=0;j<4;j++)
                {
                    int a=x+dx[j],b=y+dy[j],c=que.front().first;
                    if(a>=0&&a<n&&b>=0&&b<m)
                    {
                        if(grid[a][b]==3)mn=min(mn,c);
                        else if(grid[a][b]==0&&c<ans[a][b])
                        {
                            ans[a][b]=c;
                            que.push({c+1,{a,b}});
                        }
                        else if(grid[a][b]==2&&!st[a][b])
                        {
                            st[a][b]=1;
                            que.push({0,{a,b}});
                        }
                    }
                }
                que.pop();
            }
        }
        return mn;
    }
};