【LeetCode】第934题——最短的桥(难度:中等)
【LeetCode】第934题——最短的桥(难度:中等)
- 题目描述
- 解题思路
- 代码详解
- 注意点
题目描述
在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)
现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。
返回必须翻转的 0 的最小数目。(可以保证答案至少是 1 。)
示例 1:
输入:A = [[0,1],[1,0]]
输出:1示例 2:
输入:A = [[0,1,0],[0,0,0],[0,0,1]]
输出:2示例 3:
输入:A = [[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
提示:
2 <= A.length == A[0].length <= 100
A[i][j] == 0 或 A[i][j] == 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-bridge
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
DFS找出两个大陆并做标记1和2,对1号大陆的海域按BFS一层层地找寻2号大陆的边界,层数就和桥的长度成正相关。
代码详解
class Solution {public int shortestBridge(int[][] A) {int Ar = A.length;int Ac = A[0].length;int[][] map = buildMap(A); // 对原地图进行“上色”-->标记为1号大陆和2号大陆Set<Integer> set = new HashSet<>(); // 存放2号大陆/目标大陆的各板块“位置”Queue<Node> queue = new LinkedList<>(); // 利用队列进行BFS// 1号大陆放入队列queue,2号大陆放入集合setfor(int i = 0; i < Ar; ++i) {for(int j = 0; j < Ac; ++j) {if(map[i][j] == 1) {queue.offer(new Node(i, j, 0));} else if(map[i][j] == 2) {set.add(i * Ac + j);}}}// BFSwhile(!queue.isEmpty()) {Node node = queue.poll();if(set.contains(node.r * Ac + node.c)) {return node.d - 1; // 因为当前节点已经遍历到2号大陆“陆上”了,而2号大陆内部不算入桥的长度,因此减去1}if(node.r != 0 && map[node.r-1][node.c] != 1) {queue.offer(new Node(node.r-1, node.c, node.d+1));map[node.r-1][node.c] = 1;}if(node.r != Ac - 1 && map[node.r+1][node.c] != 1) {queue.offer(new Node(node.r+1, node.c, node.d+1));map[node.r+1][node.c] = 1;}if(node.c != 0 && map[node.r][node.c-1] != 1) {queue.offer(new Node(node.r, node.c-1, node.d+1));map[node.r][node.c-1] = 1;}if(node.c != Ac - 1 && map[node.r][node.c+1] != 1) {queue.offer(new Node(node.r, node.c+1, node.d+1));map[node.r][node.c+1] = 1;}}return 1; // 桥长至少为1}// 上色方法public int[][] buildMap(int[][] A) {int Ar = A.length;int Ac = A[0].length;int type = 1; // 先给1号大陆上色,再给2号大陆上色int[][] map = new int[Ar][Ac]; // 上色后的地图,方法返回值// 因为是深搜,所以一块大陆完整地遍历完后才会遍历第二块大陆// 利用stack进行循环的深搜for(int i = 0; i < Ar; ++i) {for(int j = 0; j < Ac; ++j) {if(map[i][j] == 0 && A[i][j] == 1) {Stack<Integer> stack = new Stack<>();stack.push(i * Ac + j);while(!stack.isEmpty()) {int temp = stack.pop();int ni = temp / Ac;int nj = temp % Ac;map[ni][nj] = type; // 上色// 上下左右块按条件入栈if(ni != 0 && A[ni-1][nj] == 1 && map[ni-1][nj] == 0) {stack.push((ni-1) * Ac + nj);}if(ni != Ar - 1 && A[ni+1][nj] == 1 && map[ni+1][nj] == 0) {stack.push((ni+1) * Ac + nj);}if(nj != 0 && A[ni][nj-1] == 1 && map[ni][nj-1] == 0) {stack.push(ni * Ac + nj - 1);}if(nj != Ac - 1 && A[ni][nj+1] == 1 && map[ni][nj+1] == 0) {stack.push(ni * Ac + nj + 1);}}++type; // 1号大陆遍历完了,遍历2号大陆}}}return map;}
}class Node {int r; // 行int c; // 列int d; // 层数/深度public Node(int r, int c, int d) {this.r = r;this.c = c;this.d = d;}
}
注意点
- DFS对大陆位置进行遍历,用BFS去遍历海洋部分,以达到“一层一层建桥”的效果,方便通过层数确定桥长。思路比较难以想到,但看完答案后容易想通,只是代码量相对多。
- 基础的友情链接:【LeetCode】第200题——岛屿数量(难度:中等)
【LeetCode】第934题——最短的桥(难度:中等)相关推荐
- 【LeetCode】934. 最短的桥
题目 934. 最短的桥 给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域. 岛 是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连.grid ...
- 【LeetCode每日一题】1723. 完成所有工作的最短时间
[LeetCode每日一题]1723. 完成所有工作的最短时间 [1] 1723. 完成所有工作的最短时间 [2] 473. 火柴拼正方形 [1] 1723. 完成所有工作的最短时间 题目: 给你一个 ...
- 【LeetCode】第37题——解数独(难度:困难)
[LeetCode]第37题--解数独(难度:困难) 题目描述 解题思路 代码详解 注意点 题目描述 编写一个程序,通过填充空格来解决数独问题. 数独的解法需 遵循如下规则: 数字 1-9 在每一行只 ...
- Leetcode最短的桥
934. 最短的桥 思路:先通过任意搜索方法找到其中一个岛屿 然后利用广度优先搜索,查找其与另一个岛屿的最短距离. class Solution {public:vector<int> d ...
- Leetcode每日一题总目录(动态更新。。。)
0. 概要 leecode每日一题(也可能多题)题解跟踪记录及总目录. 常用算法解题思路和技巧及数据结构: 预处理:数组排序(954),哈希表... 双指针法 682,125,905 单向链表 2 双 ...
- LeetCode算法刷题目录 (Java)
目录 1.数学基础 1.1.位运算 1.2.其它 2.数据结构 2.1.线性表 2.1.1.数组(双指针) 2.1.2.链表(双指针) 2.1.3.栈 2.1.4.队列 2.1.5.字符串 2.1.6 ...
- leetcode每日一题系列——787. K 站中转内最便宜的航班
787. K 站中转内最便宜的航班 难度中等346收藏分享切换为英文接收动态反馈 有 n 个城市通过一些航班连接.给你一个数组 flights ,其中 flights[i] = [fromi, toi ...
- leetcode 高薪_利用两种不同的方法解LeetCode第1312题:让字符串成为回文串的最少插入次数
题目描述(难度困难) 给你一个字符串 s ,每一次操作你都可以在字符串的任意位置插入任意字符.请你返回让 s 成为回文串的 最少操作次数 . 「回文串」是正读和反读都相同的字符串. 示例 1: 输入: ...
- LeetCode(SQL)难度-中等
LeetCode(SQL)难度-中等 注:排名知识点(题目1->思路来源于牛客-小数志(公众号)) 连续排名,例如3000,2000,2000,1000排名结果为1-2-3-4,体现同薪不同名, ...
- LeetCode每日一题——1812. 判断国际象棋棋盘中一个格子的颜色
LeetCode每日一题系列 题目:1812. 判断国际象棋棋盘中一个格子的颜色 难度:简单 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 给你一个坐标 coordinates ...
最新文章
- 零基础小白学Java难度大不大
- mysql可视化工具-navicat的下载和使用
- Java ServletContext 详解
- Java生产环境下性能监控与调优详解 第8章 JVM字节码与Java代码层调优
- mysql滚动条不见了,11-JS处理滚动条
- 数据结构与算法笔记(一) 程序性能分析
- Cisco Nexus-1000v授权
- Express框架的请求处理~非常详细
- 【Vijos1659】河蟹王国
- 计算机丢失disrupt,disrupt造句
- facebuilder免费版_Face Blender(人脸混合器)V2018 最新免费版
- 介绍中国传统节日的网页html,介绍中国传统节日
- 我们都是被宫崎骏爱过的孩子
- SAP中销售项目开票的初步分析
- Unity接入穿山甲广告(使用unity插件SDK接入)看这一篇就够了
- 关于微擎模块,点击上传图片无反映问题。
- Ant Design Vue 动态路由
- 自动摘要生成(三):词向量相似度与有效词含量
- 2023年上半年软考报考指南~
- google map 地理编码API的两种方式