主页有其他数据结构内容(持续更新中)
难度:Medium
代码:
class Solution {
private:
queue<pair<int, int>> points;
int direction[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
void dfs(vector<vector<int>>& grid, int x, int y) {
grid[x][y] = 2;
for(int k = 0; k < 4; k++) {
int nextX = x + direction[k][0];
int nextY = y + direction[k][1];
if(nextX >= 0 && nextX < grid.size() && nextY >= 0 && nextY < grid[0].size()) {
if(grid[nextX][nextY] == 2){
// 属于同一块岛屿并且已经被标记为2了
continue;
}
if(grid[nextX][nextY] == 1) {
// 属于同一块岛屿但尚未标记
dfs(grid, nextX, nextY);
}
if(grid[nextX][nextY] == 0) {
// 是距离最近的海洋
points.push({nextX, nextY}); // 入队,方便后续bfs
}
}
}
}
public:
int shortestBridge(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
bool isFind = false;
for (int i = 0; i < m; i++) {
if (isFind) {
break;
}
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
// 调用dfs把这个岛屿都标记为2
dfs(grid, i, j);
isFind = true;
break;
}
}
}
// 使用bfs寻找第二个岛屿,把过程中的0变成2
int res = 0;
while (!points.empty()) {
res++;
int size = points.size();
// 此处的while循环是为了控制元素出队的次数:只能让当前队列里的所有元素出队,不能让新加入的元素出队
while (size--) {
auto [x, y] = points.front();
grid[x][y] = 2; // 填海造陆(队列里都是离陆地最近的海)
points.pop();
for (int k = 0; k < 4; k++) {
int nextX = x + direction[k][0];
int nextY = y + direction[k][1];
if (nextX >= 0 && nextX < m && nextY >= 0 && nextY < n) {
if (grid[nextX][nextY] == 2) {
continue;
}
else if (grid[nextX][nextY] == 1) {
// 说明找到了另一个岛屿
return res;
}
else {
// 说明遇到了离当前陆地最近的海洋,需要将其入队
points.push({nextX, nextY});
grid[nextX][nextY] = 2;
}
}
}
}
}
return res;
}
};