2021-07-28:最短的桥。在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的
2021-07-28:最短的桥。在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的 0 的最小数目。(可以保证答案至少是 1 。)
福大大 答案2021-07-28:
宽度优先遍历。找到第一个岛,广播一次,增加一层,碰到第二个岛为止。层数就是需要的返回值。
时间复杂度:O(NM)。
空间复杂度:O(NM)。
代码用golang编写。代码如下:
package main
import (
"fmt"
"math"
)
func main() {
m := [][]int{{0, 1, 0}, {0, 0, 0}, {0, 0, 1}}
ret := shortestBridge(m)
fmt.Println(ret)
}
func shortestBridge(m [][]int) int {
N := len(m)
M := len(m[0])
all := N * M
island := 0
curs := make([]int, all)
nexts := make([]int, all)
records := make([][]int, 2)
for i := 0; i < 2; i++ {
records[i] = make([]int, all)
}
for i := 0; i < N; i++ {
for j := 0; j < M; j++ {
if m[i][j] == 1 { // 当前位置发现了1!
// 把这一片的1,都变成2,同时,抓上来了,这一片1组成的初始队列
// curs, 把这一片的1到自己的距离,都设置成1了,records
queueSize := infect(m, i, j, N, M, curs, 0, records[island])
V := 1
for queueSize != 0 {
V++
// curs里面的点,上下左右,records[点]==0, nexts
queueSize = bfs(N, M, all, V, curs, queueSize, nexts, records[island])
tmp := curs
curs = nexts
nexts = tmp
}
island++
}
}
}
min := math.MaxInt64
for i := 0; i < all; i++ {
min = getMin(min, records[0][i]+records[1][i])
}
return min - 3
}
func getMin(a int, b int) int {
if a < b {
return a
} else {
return b
}
}
// 当前来到m[i][j] , 总行数是N,总列数是M
// m[i][j]感染出去(找到这一片岛所有的1),把每一个1的坐标,放入到int[] curs队列!
// 1 (a,b) -> curs[index++] = (a * M + b)
// 1 (c,d) -> curs[index++] = (c * M + d)
// 二维已经变成一维了, 1 (a,b) -> a * M + b
// 设置距离record[a * M +b ] = 1
func infect(m [][]int, i int, j int, N int, M int, curs []int, index int, record []int) int {
if i < 0 || i == N || j < 0 || j == M || m[i][j] != 1 {
return index
}
// m[i][j] 不越界,且m[i][j] == 1
m[i][j] = 2
p := i*M + j
record[p] = 1
// 收集到不同的1
curs[index] = p
index++
index = infect(m, i-1, j, N, M, curs, index, record)
index = infect(m, i+1, j, N, M, curs, index, record)
index = infect(m, i, j-1, N, M, curs, index, record)
index = infect(m, i, j+1, N, M, curs, index, record)
return index
}
// 二维原始矩阵中,N总行数,M总列数
// all 总 all = N * M
// V 要生成的是第几层 curs V-1 nexts V
// record里面拿距离
func bfs(N int, M int, all int, V int, curs []int, size int, nexts []int, record []int) int {
nexti := 0 // 我要生成的下一层队列成长到哪了?
for i := 0; i < size; i++ {
// curs[i] -> 一个位置
up := twoSelectOne(curs[i] < M, -1, curs[i]-M)
down := twoSelectOne(curs[i]+M >= all, -1, curs[i]+M)
left := twoSelectOne(curs[i]%M == 0, -1, curs[i]-1)
right := twoSelectOne(curs[i]%M == M-1, -1, curs[i]+1)
if up != -1 && record[up] == 0 {
record[up] = V
nexts[nexti] = up
nexti++
}
if down != -1 && record[down] == 0 {
record[down] = V
nexts[nexti] = down
nexti++
}
if left != -1 && record[left] == 0 {
record[left] = V
nexts[nexti] = left
nexti++
}
if right != -1 && record[right] == 0 {
record[right] = V
nexts[nexti] = right
nexti++
}
}
return nexti
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
执行结果如下:

2021-07-28:最短的桥。在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的的更多相关文章
- F - Goldbach`s Conjecture 对一个大于2的偶数n,找有多少种方法使两个素数的和为n;保证素数a<=b; a+b==n; a,b都为素数。
/** 题目:F - Goldbach`s Conjecture 链接:https://vjudge.net/contest/154246#problem/F 题意:对一个大于2的偶数n,找有多少种方 ...
- Leetcode之深度+广度优先搜索(DFS+BFS)专题-934. 最短的桥(Shortest Bridge)
Leetcode之广度优先搜索(BFS)专题-934. 最短的桥(Shortest Bridge) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary ...
- [Swift]LeetCode934. 最短的桥 | Shortest Bridge
In a given 2D binary array A, there are two islands. (An island is a 4-directionally connected grou ...
- 基于opencv3.0和下的条形码与二维码识别
其中对条码与二维码的识别分为以下4个步骤 1. 利用opencv和Zbar(或者Zxing)对标准的条形码图片(即没有多余背景干扰,且图片没有倾斜)进行解码,将解码信息显示出来,并与原始信息对比. 2 ...
- 剑指offer1: 组类型——二维数组中的查找(给定一个数字,查找是否在该数组中)
1. 思路: 缩小范围 2. 方法: (1)要查找的数字等于数组中的数字,结束查找过程: (2)要查找的数字小于数组中的数字,去除该数字右边的数字,在剩下的数字里查找: (3)要查找的数字大于数组中的 ...
- 2021.07.17 题解 CF1385E Directing Edges(拓扑排序)
2021.07.17 题解 CF1385E Directing Edges(拓扑排序) CF1385E Directing Edges - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) ...
- 2021.07.26 P1011 车站(斐波那契数列)
2021.07.26 P1011 车站(斐波那契数列) [P1011 NOIP1998 提高组] 车站 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.改变形式的斐波那契 ...
- 2021.07.20 P3951 小凯的疑惑(最大公因数,未证)
2021.07.20 P3951 小凯的疑惑(最大公因数,未证) 重点: 1.最大公因数 题意: 求ax+by最大的表示不了的数(a,b给定 x,y非负). 分析: 不会.--2021.07.20 代 ...
- 2021.07.09 K-D树
2021.07.09 K-D树 前置知识 1.二叉搜索树 2.总是很长的替罪羊树 K-D树 建树 K-D树具有二叉搜索树的形态,对于每一个分类标准,小于标准的节点在父节点左边,大于标准的节点在父节点右 ...
- 2021.07.02 P1383 高级打字机题解(可持久化平衡树)
2021.07.02 P1383 高级打字机题解(可持久化平衡树) 分析: 从可以不断撤销并且查询不算撤销这一骚操作可以肯定这是要咱建一棵可持久化的树(我也只会建可持久化的树,当然,还有可持久化并查集 ...
随机推荐
- msfconsole的使用
msfconsole是metasploit中的一个工具: msfconsole集成了很多漏洞的利用的脚本,并且使用起来很简单的网络安全工具 在终端输入msfconsole命令即可进入msf的控制台,m ...
- Android笔记--视图显示
视图显示 视图的宽高设置 方式一:在.xml文件中设置视图的宽和高 通过调用android:layout_width设置视图的宽 通过调用android:layout_height设置视图的高 宽和高 ...
- Linux0.11源码学习(四)
Linux0.11源码学习(四) linux0.11源码学习笔记 参考资料: https://github.com/sunym1993/flash-linux0.11-talk https://git ...
- 第五章 C控制语句:循环
一个好的语言应该能够提供以下三种形式的程序流: ●顺序执行语句序列(顺序) ●在满足某个条件之前反复执行一个语句序列(循环) ●通过进行一个判断在两个可选的语句序列之间选择执行(分支) 5.1whil ...
- 7个角度,用 ChatGPT 玩转机器学习
大家好,我是机器学习科普创作者章北海mlpy,探索更高效的学习方法是我一直等追求.现在的初学者太幸福了,可以利用ChatGPT来帮助你学习机器学习的各个方面. 比如[个人首测]百度文心一言 VS GP ...
- 从零开始学习 Java 系列之你为什么要学 Java?
全文大约[4000]字,不说废话,只讲可以让你学到技术.明白原理的纯干货! 在正式开始本系列教程之前,壹哥希望先用一篇文章,来扫清你学习前的认知障碍.请坚定自己的学习信念,不要半途而废浪费时间,壹哥希 ...
- gulp基本操作
1.安装淘宝镜像 npm install cnpm -g --registry=https://registry.npm.taobao.org cnpm -v 2.生成项目描述文件 package.j ...
- WPF 界面布局、常用控件入门教程实例 WPF入门学习控件快速教程例子 WPF上位机、工控串口通信经典入门
WPF(Windows Presentation Foundation)是一种用于创建 Windows 桌面应用程序的框架,它提供了丰富的控件库和灵活的界面布局,可以创建现代化的用户界面.下面是 WP ...
- [Linux/Redis]搭建Redis集群
1 基本信息 3台服务器(CentOS7.3) 192.168.1.101 node101 192.168.1.102 node102 192.168.1.103 node103 2 单机 安装 Re ...
- 【python基础】五大数据类型及常用方法
1. 数据类型概述 python中的字符串,列表,元组,字典,集合这五种数据类型均是可迭代的,可以使用for循环访问,涵盖了三类数据结构分别为序列.散列.集合. 序列: 字符串 str 列表 list ...