In a given 2D binary array `A`, there are two islands.  (An island is a 4-directionally connected group of `1`s not connected to any other 1s.)

Now, we may change 0s to 1s so as to connect the two islands together to form 1 island.

Return the smallest number of 0s that must be flipped.  (It is guaranteed that the answer is at least 1.)

Example 1:

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

Example 2:

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

Example 3:

Input: [[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

Note:

  1. 1 <= A.length = A[0].length <= 100
  2. A[i][j] == 0 or A[i][j] == 1

这道题说是有一个只有0和1的二维数组,其中连在一起的1表示岛屿,现在假定给定的数组中一定有两个岛屿,问最少需要把多少个0变成1才能使得两个岛屿相连。在 LeetCode 中关于岛屿的题目还不少,但是万变不离其宗,核心都是用 DFS 或者 BFS 来解,有些还可以用联合查找 Union Find 来做。这里要求的是最小值,首先预定了一个 BFS,这就相当于洪水扩散一样,一圈一圈的,用的就是 BFS 的层序遍历。好,现在确定了这点后,再来想,这里并不是从某个点开始扩散,而是要从一个岛屿开始扩散,那么这个岛屿的所有的点都是 BFS 的起点,都是要放入到 queue 中的,所以要先来找出一个岛屿的所有点。找的方法就是遍历数组,找到第一个1的位置,然后对其调用 DFS 或者 BFS 来找出所有相连的1,先来用 DFS 的方法,对第一个为1的点调用递归函数,将所有相连的1都放入到一个队列 queue 中,并且将该点的值改为2,然后使用 BFS 进行层序遍历,每遍历一层,结果 res 都增加1,当遇到1时,直接返回 res 即可,参见代码如下:


解法一:

class Solution {
public:
int shortestBridge(vector<vector<int>>& A) {
int res = 0, n = A.size(), startX = -1, startY = -1;
queue<int> q;
vector<int> dirX{-1, 0, 1, 0}, dirY = {0, 1, 0, -1};
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (A[i][j] == 0) continue;
startX = i; startY = j;
break;
}
if (startX != -1) break;
}
helper(A, startX, startY, q);
while (!q.empty()) {
for (int i = q.size(); i > 0; --i) {
int t = q.front(); q.pop();
for (int k = 0; k < 4; ++k) {
int x = t / n + dirX[k], y = t % n + dirY[k];
if (x < 0 || x >= n || y < 0 || y >= n || A[x][y] == 2) continue;
if (A[x][y] == 1) return res;
A[x][y] = 2;
q.push(x * n + y);
}
}
++res;
}
return res;
}
void helper(vector<vector<int>>& A, int x, int y, queue<int>& q) {
int n = A.size();
if (x < 0 || x >= n || y < 0 || y >= n || A[x][y] == 0 || A[x][y] == 2) return;
A[x][y] = 2;
q.push(x * n + y);
helper(A, x + 1, y, q);
helper(A, x, y + 1, q);
helper(A, x - 1, y, q);
helper(A, x, y - 1, q);
}
};

我们也可以使用 BFS 来找出所有相邻的1,再加上后面的层序遍历的 BFS,总共需要两个 BFS,注意这里第一个 BFS 不需要是层序遍历的,而第二个 BFS 是必须层序遍历,可以对比一下看一下这两种写法有何不同,参见代码如下:


解法二:

class Solution {
public:
int shortestBridge(vector<vector<int>>& A) {
int res = 0, n = A.size();
queue<int> q, que;
vector<int> dirX{-1, 0, 1, 0}, dirY = {0, 1, 0, -1};
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (A[i][j] == 0) continue;
A[i][j] = 2;
que.push(i * n + j);
break;
}
if (!que.empty()) break;
}
while (!que.empty()) {
int t = que.front(); que.pop();
q.push(t);
for (int k = 0; k < 4; ++k) {
int x = t / n + dirX[k], y = t % n + dirY[k];
if (x < 0 || x >= n || y < 0 || y >= n || A[x][y] == 0 || A[x][y] == 2) continue;
A[x][y] = 2;
que.push(x * n + y);
}
}
while (!q.empty()) {
for (int i = q.size(); i > 0; --i) {
int t = q.front(); q.pop();
for (int k = 0; k < 4; ++k) {
int x = t / n + dirX[k], y = t % n + dirY[k];
if (x < 0 || x >= n || y < 0 || y >= n || A[x][y] == 2) continue;
if (A[x][y] == 1) return res;
A[x][y] = 2;
q.push(x * n + y);
}
}
++res;
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/934

类似题目:

Making A Large Island

Number of Distinct Islands II

Max Area of Island

Number of Distinct Islands

Island Perimeter

Number of Islands II

Number of Islands

参考资料:

https://leetcode.com/problems/shortest-bridge/

https://leetcode.com/problems/shortest-bridge/discuss/189315/Java-DFS%2BBFS-traverse-the-2D-array-once

https://leetcode.com/problems/shortest-bridge/discuss/189293/C%2B%2B-BFS-Island-Expansion-%2B-UF-Bonus

https://leetcode.com/problems/shortest-bridge/discuss/189321/Java-DFS-find-the-island-greater-BFS-expand-the-island

[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)

[LeetCode] 934. Shortest Bridge 最短的桥梁的更多相关文章

  1. LeetCode 934. Shortest Bridge

    原题链接在这里:https://leetcode.com/problems/shortest-bridge/ 题目: In a given 2D binary array A, there are t ...

  2. LC 934. Shortest Bridge

    In a given 2D binary array A, there are two islands.  (An island is a 4-directionally connected grou ...

  3. 【LeetCode】934. Shortest Bridge 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS + BFS 相似题目 参考资料 日期 题目地 ...

  4. 【leetcode】934. Shortest Bridge

    题目如下: In a given 2D binary array A, there are two islands.  (An island is a 4-directionally connecte ...

  5. [LeetCode] 214. Shortest Palindrome 最短回文串

    Given a string s, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  6. Leetcode之深度+广度优先搜索(DFS+BFS)专题-934. 最短的桥(Shortest Bridge)

    Leetcode之广度优先搜索(BFS)专题-934. 最短的桥(Shortest Bridge) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary ...

  7. [leetcode]244. Shortest Word Distance II最短单词距离(允许连环call)

    Design a class which receives a list of words in the constructor, and implements a method that takes ...

  8. [LeetCode] 243. Shortest Word Distance 最短单词距离

    Given a list of words and two words word1 and word2, return the shortest distance between these two ...

  9. [LeetCode] 244. Shortest Word Distance II 最短单词距离 II

    This is a follow up of Shortest Word Distance. The only difference is now you are given the list of ...

随机推荐

  1. 数组NSArray与NSMutableArray的常用方法

    数组中可以放任何类型的数据,并且一个数组中的元素类型可以不一致.只要是(id类型)对象. NSArray 1.初始化 NSArray *array = @[]; 2.初始化,最后需要以nil结尾 NS ...

  2. pytorch深度学习神经网络实现手写字体识别

    利用平pytorch搭建简单的神经网络实现minist手写字体的识别,采用三层线性函数迭代运算,使得其具备一定的非线性转化与运算能力,其数学原理如下: 其具体实现代码如下所示:import torch ...

  3. 302重定向之后,session中存储的值没了

    302重定向之后,session中存储的值没了

  4. mathematica练习程序(第一章 Mathematica的基本量)

    虽然过去有用Mathematica解过一些问题,不过对这个语言并没有系统学习过. 所以最近想重新把Mathematica系统的学一遍. 偶然在B站上找到了这样一组教程:https://www.bili ...

  5. Linux命令:ls命令

    ls命令:(list directory contents),列出目录内容 用法:ls [options] [file_or_dirs] ls命令常用选项 ls -l 显示文件的长格式信息 ls -d ...

  6. HTML多条件筛选商品

    今天同事接到一个类似于JD的按条件筛选商品的功能,同事把这个锅出色的甩给了我,俺就勉为其难的解决了这个问题. 首先我们来理清一下思路: 1.条件切换时,tab选项卡肯定要跟着切换,而且只是一个大类条件 ...

  7. 一个自己实现的Vector(只能处理基本类型数据)

    一个自己实现的Vector(只能处理基本类型数据) string 类型不行 bool char* int double float long long 等基本s类型可用 使用模板类实现.底层为数组实现 ...

  8. 关于python中format占位符中的 {!} 参数

    在看celery的时候,发现里面有这么一句 print('Request: {0!r}'.format(self.request)) 关于里面的{0!r}是什么意思翻了一下文档. 文档里是这么描述的 ...

  9. jQuery新的事件绑定机制on()示例应用

    投稿:whsnow 字体:[增加 减小] 类型:转载   从jQuery1.7开始,jQuery引入了全新的事件绑定机制,on()和off()两个函数统一处理事件绑定,下面通过示例为大家介绍下     ...

  10. 【Luogu4448】 [AHOI2018初中组]球球的排列

    题意 有 \(n\) 个球球,每个球球有一个属性值 .一个合法的排列满足不存在相邻两个球球的属性值乘积是完全平方数.求合法的排列数量对 \(10^9+7\) 取膜. \(n\le 300\) (本题数 ...