Leetcode 937 最短的桥
问题重述
在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)
现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。
返回必须翻转的 0 的最小数目。(可以保证答案至少是 1。)
示例 1:
输入:[[0,1],[1,0]] 输出:1
示例 2:
输入:[[0,1,0],[0,0,0],[0,0,1]] 输出:2
就是1表示陆地,0是海洋,1连在一起为一整块陆地,一共有两片陆地,问两片陆地的最短距离。
思路
通过第一次遍历,将第一个陆地置为2,然后利用广度优先搜索,找到第一个最近的岛屿,并且再搜索的时候将沿途的海洋全部填充为2.代码简单易懂。
最终代码
class Solution {
public:
vector<int> direction{-1, 0, 1, 0, -1};
int shortestBridge(vector<vector<int>>& A) {
int m = A.size(), n = A[0].size();
queue<pair<int, int>> points;
bool flipped = false;
for (int i = 0; i < m; ++i) {//寻找第一个岛屿,将陆地置为2;
if (flipped) break;
for (int j = 0; j < n; ++j) {
if (A[i][j] == 1) {
dfs(points, A, m, n, i, j);
flipped = true;
break;
}
}
}
int x, y;
int level = 0;
while (!points.empty()) {
++level;
int n_points = points.size();
while (n_points--) {
auto [r, c] = points.front();
points.pop();//栈顶第一个元素弹出;
for (int k = 0; k < 4; ++k) {
x = r +direction[k], y = c + direction[k+1];
if (x >= 0 && y >=0 && x < m && y < n) {
if (A[x][y] == 2) {
continue;
}
if (A[x][y] == 1) {
return level;
}
points.push({x, y});
A[x][y] = 2;//将沿途中的0全部置为2,填地;
}
}
}
}
return 0;
}
void dfs(queue<pair<int, int>>& points, vector<vector<int>>& A, int m, int n, int i, int j) {
if (i < 0 || j < 0|| i == m || j == n || A[i][j]==2) {
return;
}
if (A[i][j] == 0) {
points.push({i, j});
return;
}
A[i][j] = 2;
dfs(points, A, m, n, i + 1, j);
dfs(points, A, m, n, i - 1, j);
dfs(points, A, m, n, i, j + 1);
dfs(points, A, m, n, i, j - 1);
}
};