• 934. 最短的桥



    前言

    在给定的二维二进制数组 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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
  • 相关阅读:
    Cadence Allegro焊盘设计经验原则
    ruoyi登录功能源码分析
    苏宁API接口解析,实现按关键字搜索suning商品
    miniui表格data-grid 锁定指定列
    java-net-php-python-jspm校园线上零食屋计算机毕业设计程序
    Leetcode(524)——通过删除字母匹配到字典里最长单词
    微信小程序云开发教程——墨刀原型工具入门(表单组件)
    计算机毕业设计(附源码)python智慧门诊综合管理系统
    Nautilus Chain全球行分享会,上海站圆满举办
    【构建ML驱动的应用程序】第 10 章 :为模型构建安全措施
  • 原文地址:https://blog.csdn.net/xiaolu567/article/details/126078073