最短的桥
题解思路:
明确两个岛不会相连,所求翻转0的最小数目,就是两个岛之间的最短距离,那么距离该怎么求,想到用广度优先,让某一岛的所有结点都向四个方向扩展一圈,视为step=1;如果在扩展中遇到了岛2,那么说明以及连接成了一座岛,立即return step;中断扩展。
扩展一圈完成才能step++
int shortestBridge(int** grid, int gridSize, int* gridColSize) {
int n = gridSize;
int dirs[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};//上下左右四个方向
int *island = (int *)malloc(sizeof(int) * n * n); //第一座岛的位置集合
int *queue = (int *)malloc(sizeof(int) * n * n);//岛1的扩展队列,广度优先搜索队列
int head = 0, tail = 0;//队头,队尾
//n x n矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {//遇到一个岛的一块
queue[tail++] = i * n + j;//
grid[i][j] = -1;//与另一岛做区别,在此对1岛都置-1
int islandSize = 0;
while (head != tail) {//队不空
int x = queue[head] / n;
int y = queue[head] % n;
island[islandSize++] = queue[head];
head++;
for (int k = 0; k < 4; k++) {//上下左右广度搜索
int nx = x + dirs[k][0];
int ny = y + dirs[k][1];
if (nx >= 0 && ny >= 0 && nx < n && ny < n && grid[nx][ny] == 1) {
queue[tail++] = nx * n + ny;
grid[nx][ny] = -1;
}
}
}//执行到这一步就已经标记完成1岛的全部位置,全部置为-1,因为岛是相连的,找到一个1,再对其进行广度遍历,则会找到全部位置
//下面就是对1岛进行扩展
head = tail = 0;
for (int i = 0; i < islandSize; i++) {
queue[tail++] = island[i];
}
int step = 0;
while (head != tail) {
int sz = tail - head;
for (int i = 0; i < sz; i++) {//一次广度优先搜索完成,岛屿扩展一圈,下面step++
int x = queue[head] / n;
int y = queue[head] % n;
head++;
for (int k = 0; k < 4; k++) {
int nx = x + dirs[k][0];
int ny = y + dirs[k][1];//一位数组存储,恢复二维状态
if (nx >= 0 && ny >= 0 && nx < n && ny < n) {
if (grid[nx][ny] == 0) {//不超边界并且是水域,扩展该位置
queue[tail++] = nx * n + ny;
grid[nx][ny] = -1;
} else if (grid[nx][ny] == 1) {//偶遇2岛,立即结束,返回step
free(queue);
free(island);
return step;
}
}
}
}
step++;
}
}
}
}
return 0;
}
/*
肯定有两个岛屿
上下左右找一条最短的路将两个岛连起来
*/
总结:中等题目好难,与图有关的题好复杂,时间复杂度一般也高,代码量也多,真的太难了,理解原理还行,只不过自己想不出来,看过题解大概懂了,不过代码根本无从下手,对bfs理解不够深入,运用就更扯了,题解代码看了一小时,写了注释,基本看懂。