题目:
给你一个大小为 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]
为0
或1
grid
中恰有两个岛
思路:
经典的bfs的做法,找到一个岛屿,然后将这个岛屿上的所以节点每一次外四个方向走一步;走了n步,在n+1这一步中,第i个节点走这一步到了另一个岛屿,返回n即可。
class Solution {
public int shortestBridge(int[][] grid) {
int[] fx = {0,0,1,0,-1};
int[] fy = {0,1,0,-1,0};
Queue<int[]> queue1 = new ArrayDeque<>();
Queue<int[]> queue2 = new ArrayDeque<>();
int n=grid.length;
a:for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(grid[i][j]==1){
queue1.offer(new int[]{i,j});
grid[i][j]=-1;
while (!queue1.isEmpty()){
int[] t=queue1.poll();
for(int k=1;k<=4;k++){
int x=t[0]+fx[k];
int y=t[1]+fy[k];
if(x>=0&&x<n&&y>=0&&y<n&&grid[x][y]==1){
grid[x][y]=-1;
queue1.offer(new int[]{x,y});
}
}
}
break a;
}
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(grid[i][j]==-1)queue2.offer(new int[]{i,j});
}
int ans = 0;
while (!queue2.isEmpty()){
int size = queue2.size();
for(int s=0; s<size;s++){
int[] t = queue2.poll();
for(int i=1;i<=4;i++){
int x=t[0]+fx[i];
int y=t[1]+fy[i];
if(x>=0&&x<n&&y>=0&&y<n&&grid[x][y]==1){
return ans;
}
if(x>=0&&x<n&&y>=0&&y<n&&grid[x][y]==0){
grid[x][y]=-1;
queue2.offer(new int[]{x,y});
}
}
}
ans++;
}
return 0;
}
}