给你一个大小为 n x n
的二元矩阵 grid
,其中 1
表示陆地,0
表示水域。
岛 是由四面相连的 1
形成的一个最大组,即不会与非组内的任何其他 1
相连。grid
中 恰好存在两座岛 。
你可以将任意数量的 0
变为 1
,以使两座岛连接起来,变成 一座岛 。
返回必须翻转的 0
的最小数目。
示例 1:
输入:grid = [[0,1],[1,0]] 输出:1
class Solution {
//此题等价于找出两座岛屿之间的最短路径
int[] dx = {0, 0, 1, -1};
int[] dy = {1, -1, 0, 0};
Queue<int[]> queue = new ArrayDeque<>();
public int shortestBridge(int[][] grid) {
//首先dfs找出第一个岛屿所有的点位,将其全部变为2
aa:
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
dfs(grid, i, j);
break aa;
}
}
}
//然后bfs广搜,直到遇到了1
int ans = 0;//距离数
while (true) {
int size= queue.size();
for (int i = size; i > 0; i--) {//遍历此时队列的所有元素,其距离都一样,为ans
int[] p = queue.poll();//从队首开始遍历,并且删除队首(已无利用价值)
for (int j = 0; j < 4; j++) {
int x = p[0] + dx[j];
int y = p[1] + dy[j];
if (x >= 0 && y >= 0 && x < grid.length && y < grid[0].length) {
if (grid[x][y] == 1) return ans;//搜索到了对面的岛屿,返回最短距离
if (grid[x][y] == 0) {
grid[x][y] = 2;
queue.offer(new int[]{x, y});
}
}
}
}
ans++;
}
}
private void dfs(int[][] grid, int i, int j) {
if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length) return;//越界
if (grid[i][j] != 1) return;//走过了或者是水域
grid[i][j] = 2;
queue.offer(new int[]{i, j});
for (int k = 0; k < 4; k++) {
dfs(grid, i + dx[k], j + dy[k]);
}
}
}