20221025 - 934. Shortest Bridge最短的桥(广度优先搜索)

219 阅读1分钟

You are given an n×nn \times n binary matrix grid where 1 represents land and 0 represents water.

An island is a 4-directionally connected group of 1's not connected to any other 1's. There are exactly two islands in grid.

You may change 0's to 1's to connect the two islands to form one island.

Return the smallest number of 0's you must flip to connect the two islands.

Example 1

Input: grid = [[0,1],[1,0]]
Output: 1

Example 2

Input: grid = [[0,1,0],[0,0,0],[0,0,1]]
Output: 2

Example 3

Input: grid = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
Output: 1

Constraints

  • n == grid.length == grid[i].length
  • 2 <= n <= 100
  • grid[i][j] is either 0 or 1.
  • There are exactly two islands in grid.

Solution

官方题解:

题目中求最少的翻转 00 的数目等价于求矩阵中两个岛的最短距离,因此我们可以广度优先搜索来找到矩阵中两个块的最短距离。首先找到其中一座岛,然后将其不断向外延伸一圈,直到到达了另一座岛,延伸的圈数即为最短距离。广度优先搜索时,我们可以将已经遍历过的位置标记为 1-1,实际计算过程如下:

我们通过遍历找到数组 grid\textit{grid} 中的 11 后进行广度优先搜索,此时可以得到第一座岛的位置集合,记为 island\textit{island},并将其位置全部标记为 1-1。 随后我们从 island\textit{island} 中的所有位置开始进行广度优先搜索,当它们到达了任意的 11 时,即表示搜索到了第二个岛,搜索的层数就是答案。

class Solution {
public:
    int shortestBridge(vector<vector<int>>& grid) {
        int n = grid.size();
        vector<vector<int>> dirs = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
        vector<pair<int, int>> island;
        queue<pair<int, int>> qu;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    qu.emplace(i, j);
                    grid[i][j] = -1;
                    while (!qu.empty()) {
                        auto [x, y] = qu.front();
                        qu.pop();
                        island.emplace_back(x, y);
                        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) {
                                qu.emplace(nx, ny);
                                grid[nx][ny] = -1;
                            }
                        }
                    }
                    for (auto &&[x, y] : island) {
                        qu.emplace(x, y);
                    }
                    int step = 0;
                    while (!qu.empty()) {
                        int sz = qu.size();
                        for (int i = 0; i < sz; i++) {
                            auto [x, y] = qu.front();
                            qu.pop();
                            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) {
                                        qu.emplace(nx, ny);
                                        grid[nx][ny] = -1; 
                                    } else if (grid[nx][ny] == 1) {
                                        return step;
                                    }
                                }
                            }
                        }
                        step++;
                    }
                }
            }
        }
        return 0;
    }
};

算法的实现需要数据结构做支撑!快去学cpp!

题目链接:934. 最短的桥 - 力扣(LeetCode)