最短的桥
问题描述:
给你一个大小为 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
问题求解:
/* 思路: DFS + BFS */
/* 先用深度优先搜索DFS, 找到第1个岛屿, 将岛屿元素置为2, 并入队 */
/* 再用广度优先搜索BFS, 从第1个岛屿元素开始向外寻找, 找到的0置为2 */
/* 当找到第一个1时, 就返回寻找的路径step */
/* 队列结构体定义 */
typedef struct {
int x;
int y;
int step;
} Queue;
/* DFS 寻找第一个岛屿元素 */
void dfs(int **A, int ASize, int i, int j, Queue *Q, int *rear) {
if (i < 0 || i >= ASize || j < 0 || j >= ASize || A[i][j] != 1) {
return;
}
/* 元素置为2, 并入队, step置为0 */
A[i][j] = 2;
Q[(*rear)].x = i;
Q[(*rear)].y = j;
Q[(*rear)++].step = 0;
/* 上下左右继续寻找 */
dfs(A, ASize, i - 1, j, Q, rear);
dfs(A, ASize, i + 1, j, Q, rear);
dfs(A, ASize, i, j - 1, Q, rear);
dfs(A, ASize, i, j + 1, Q, rear);
return;
}
int shortestBridge(int** A, int ASize, int* AColSize){
Queue *Q = (Queue*)malloc(sizeof(Queue) * ASize * ASize);
int front = 0;
int rear = 0;
int find = 0;
int i, j, x, y, xx, yy, step;
int xShift[] = {-1, 1, 0, 0};
int yShift[] = { 0, 0, -1, 1};
/* DFS第一个岛屿 */
for (i = 0; i < ASize; i++) {
for (j = 0; j < ASize; j++) {
if (A[i][j] == 1) {
dfs(A, ASize, i, j, Q, &rear);
find = 1;
break;
}
}
/* 只寻找第一个岛屿 */
if (find == 1) {
break;
}
}
/* BFS 第一个岛屿向外扩散 */
while (front != rear) {
x = Q[front].x;
y = Q[front].y;
step = Q[front++].step;
/* 上下左右扩散 */
for (i = 0; i < 4; i++) {
xx = x + xShift[i];
yy = y + yShift[i];
if (xx < 0 || xx >= ASize || yy < 0 || yy >= ASize || A[xx][yy] == 2) {
continue;
}
if (A[xx][yy] == 1) { /* 找到另一岛屿时, 返回step */
return step;
}
A[xx][yy] = 2; /* 将扩散到的0置为2, 并入队 */
Q[rear].x = xx;
Q[rear].y = yy;
Q[rear++].step = step + 1;
}
}
free(Q);
return step;
}
问题总结:
老规矩我们先看一下官方求解。
方法一:广度优先搜索
题目中求最少的翻转 00 的数目等价于求矩阵中两个岛的最短距离,因此我们可以广度优先搜索来找到矩阵中两个块的最短距离。首先找到其中一座岛,然后将其不断向外延伸一圈,直到到达了另一座岛,延伸的圈数即为最短距离。广度优先搜索时,我们可以将已经遍历过的位置标记为 -1−1,实际计算过程如下:
我们通过遍历找到数组 \textit{grid}grid 中的 11 后进行广度优先搜索,此时可以得到第一座岛的位置集合,记为 \textit{island}island,并将其位置全部标记为 -1−1。
随后我们从 \textit{island}island 中的所有位置开始进行广度优先搜索,当它们到达了任意的 11 时,即表示搜索到了第二个岛,搜索的层数就是答案。
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/shortest-bridge/solution/zui-duan-de-qiao-by-leetcode-solution-qe44/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。