当前位置:网站首页>934. 最短的桥
934. 最短的桥
2022-07-31 01:38:00 【小卢要刷力扣题】
前言
在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)
现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。
返回必须翻转的 0 的最小数目。(可以保证答案至少是 1 。)
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shortest-bridge
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路

从第一片1广播
第二片1广播
两者广播相同位置的相加数中的最小值-3即为最短的桥
为什么要-3呢
因为有重复的部分,
第一片1到自己的距离为1,
第二片1到自己的距离也是1,
第一片1和第二片1到2这个点的距离为2-1,重复了一个1
二维变一维的技巧.
二维坐标对应的是一维坐标中的i*列数+j
一维坐标怎么判断有没有上下左右
1)a%列数=0,也就是最左边
2)a%列数=列数-1,也就是在最后一列,没有右边
3)a/行数=0,在第一行
4)a/行=行-1,在最后一行


第一片的队列curs跟record
cur记录的1的一维坐标
next代表感染的一维坐标
在第二个1中
可以往下扩展
因此next填入8,也就是正方形的位置
当队列遍历完后,next变成curs
进行下一轮的扩展
代码
public static int shortestBridge(int[][] m) {
int N = m.length;
int M = m[0].length;
int all = N * M;
int island = 0;
int[] curs = new int[all];
int[] nexts = new int[all];
int[][] records = new int[2][all];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (m[i][j] == 1) {
// 当前位置发现了1!
// 把这一片的1,都变成2,同时,抓上来了,这一片1组成的初始队列
// curs, 把这一片的1到自己的距离,都设置成1了,records
int queueSize = infect(m, i, j, N, M, curs, 0, records[island]);
int V = 1;
while (queueSize != 0) {
V++;
// curs里面的点,上下左右,records[点]==0, nexts
queueSize = bfs(N, M, all, V, curs, queueSize, nexts, records[island]);
int[] tmp = curs;
curs = nexts;
nexts = tmp;
}
island++;
}
}
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < all; i++) {
min = Math.min(min, records[0][i] + records[1][i]);
}
return min - 3;
}
// 当前来到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
public static int infect(int[][] m, int i, int j, int N, int M, int[] curs, int index, int[] record) {
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;
int p = i * M + j;
record[p] = 1;
// 收集到不同的1
curs[index++] = p;
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里面拿距离
public static int bfs(int N, int M, int all, int V, int[] curs, int size, int[] nexts, int[] record) {
int nexti = 0; // 我要生成的下一层队列成长到哪了?
for (int i = 0; i < size; i++) {
// curs[i] -> 一个位置
int up = curs[i] < M ? -1 : curs[i] - M;
int down = curs[i] + M >= all ? -1 : curs[i] + M;
int left = curs[i] % M == 0 ? -1 : curs[i] - 1;
int right = curs[i] % M == M - 1 ? -1 : curs[i] + 1;
if (up != -1 && record[up] == 0) {
record[up] = V;
nexts[nexti++] = up;
}
if (down != -1 && record[down] == 0) {
record[down] = V;
nexts[nexti++] = down;
}
if (left != -1 && record[left] == 0) {
record[left] = V;
nexts[nexti++] = left;
}
if (right != -1 && record[right] == 0) {
record[right] = V;
nexts[nexti++] = right;
}
}
return nexti;
}
边栏推荐
- MySQL (6)
- JPEG Steganalysis of Digital Image Steganography
- 太阳能板最大面积 od js
- Likou Daily Question - Day 46 - 704. Binary Search
- 倍增、DFS序
- 1.非类型模板参数 2.模板的特化 3.继承讲解
- Xiaohei's leetcode journey: 117. Fill the next right node pointer of each node II
- Interprocess communication study notes
- Shell 脚本循环遍历日志文件中的值进行求和并计算平均值,最大值和最小值
- Ticmp - 更快的让应用从 MySQL 迁移到 TiDB
猜你喜欢
随机推荐
Jiuzhou Cloud was selected into the "Trusted Cloud's Latest Evaluation System and the List of Enterprises Passing the Evaluation in 2022"
prometheus 监控概述
Dispatch Center xxl-Job
验证 XML 文档
16、注册中心-consul
Kyushu cloud as cloud computing standardization excellent member unit
认识DTU什么是4GDTU设备
1782. Count the number of point pairs Double pointer
VS warning LNK4099:未找到 PDB 的解决方案
调度中心xxl-Job
MySQL (6)
软件测试基础接口测试-入门Jmeter,你要注意这些事
简易表白小页面
rpm install postgresql12
Basic Parameters of RF Devices 1
Shell变量与赋值、变量运算、特殊变量
分布式.分布式锁
手把手教你配置Jenkins自动化邮件通知
35. 反转链表
24. Please talk about the advantages and disadvantages of the singleton pattern, precautions, usage scenarios









