leetcode0934. 最短的桥-medium
1 题目:最短的桥
官方标定难度:中
给你一个大小为 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
示例 3:
输入: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]]
输出:1
提示:
n == grid.length == grid[i].length
2 <= n <= 100
grid[i][j] 为 0 或 1
grid 中恰有两个岛
2 solution
代码
class Solution {/** 广度优先搜索:* 找到其中一个岛,以它为起点进行广度优先向外搜素,查看多少步可以搜到另一个岛*/
public:int shortestBridge(vector<vector<int>> &grid) {int m = grid.size(), n = grid[0].size();int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j]) {vector<pair<int, int>> q[2];q[0].emplace_back(i, j);vector<vector<int>> step(m, vector<int>(n, -1));step[i][j] = 0;for (int t = 0; t < q[0].size(); t++) {auto [x, y] = q[0][t];for (int k = 0; k < 4; k++) {int xx = x + dx[k];int yy = y + dy[k];if (xx >= 0 && xx < m && yy >= 0 && yy < n && grid[xx][yy] == 1 && step[xx][yy] == -1) {q[0].emplace_back(xx, yy);step[xx][yy] = 0;}}}for (int k = 0;; k++) {for (int t = 0; t < q[k & 1].size(); t++) {auto [x, y] = q[k & 1][t];for(int kk = 0; kk < 4; kk++) {int xx = x + dx[kk];int yy = y + dy[kk];if (xx >= 0 && xx < m && yy >= 0 && yy < n && step[xx][yy] == -1) {if (grid[xx][yy] == 1) {return step[x][y];} else {q[k + 1 & 1].emplace_back(xx, yy);step[xx][yy] = step[x][y] + 1;}}}}q[k & 1].clear();}}}}return 0;}
};