【LeetCode】第934题——最短的桥(难度:中等)

  • 题目描述
  • 解题思路
  • 代码详解
  • 注意点

题目描述

在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)

现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。

返回必须翻转的 0 的最小数目。(可以保证答案至少是 1 。)

  1. 示例 1:
    输入:A = [[0,1],[1,0]]
    输出:1

  2. 示例 2:
    输入:A = [[0,1,0],[0,0,0],[0,0,1]]
    输出:2

  3. 示例 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;}
}

注意点

  1. DFS对大陆位置进行遍历,用BFS去遍历海洋部分,以达到“一层一层建桥”的效果,方便通过层数确定桥长。思路比较难以想到,但看完答案后容易想通,只是代码量相对多。
  2. 基础的友情链接:【LeetCode】第200题——岛屿数量(难度:中等)

【LeetCode】第934题——最短的桥(难度:中等)相关推荐

  1. 【LeetCode】934. 最短的桥

    题目 934. 最短的桥 给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域. 岛 是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连.grid ...

  2. 【LeetCode每日一题】1723. 完成所有工作的最短时间

    [LeetCode每日一题]1723. 完成所有工作的最短时间 [1] 1723. 完成所有工作的最短时间 [2] 473. 火柴拼正方形 [1] 1723. 完成所有工作的最短时间 题目: 给你一个 ...

  3. 【LeetCode】第37题——解数独(难度:困难)

    [LeetCode]第37题--解数独(难度:困难) 题目描述 解题思路 代码详解 注意点 题目描述 编写一个程序,通过填充空格来解决数独问题. 数独的解法需 遵循如下规则: 数字 1-9 在每一行只 ...

  4. Leetcode最短的桥

    934. 最短的桥 思路:先通过任意搜索方法找到其中一个岛屿 然后利用广度优先搜索,查找其与另一个岛屿的最短距离. class Solution {public:vector<int> d ...

  5. Leetcode每日一题总目录(动态更新。。。)

    0. 概要 leecode每日一题(也可能多题)题解跟踪记录及总目录. 常用算法解题思路和技巧及数据结构: 预处理:数组排序(954),哈希表... 双指针法 682,125,905 单向链表 2 双 ...

  6. 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 ...

  7. leetcode每日一题系列——787. K 站中转内最便宜的航班

    787. K 站中转内最便宜的航班 难度中等346收藏分享切换为英文接收动态反馈 有 n 个城市通过一些航班连接.给你一个数组 flights ,其中 flights[i] = [fromi, toi ...

  8. leetcode 高薪_利用两种不同的方法解LeetCode第1312题:让字符串成为回文串的最少插入次数

    题目描述(难度困难) 给你一个字符串 s ,每一次操作你都可以在字符串的任意位置插入任意字符.请你返回让 s 成为回文串的 最少操作次数 . 「回文串」是正读和反读都相同的字符串. 示例 1: 输入: ...

  9. LeetCode(SQL)难度-中等

    LeetCode(SQL)难度-中等 注:排名知识点(题目1->思路来源于牛客-小数志(公众号)) 连续排名,例如3000,2000,2000,1000排名结果为1-2-3-4,体现同薪不同名, ...

  10. LeetCode每日一题——1812. 判断国际象棋棋盘中一个格子的颜色

    LeetCode每日一题系列 题目:1812. 判断国际象棋棋盘中一个格子的颜色 难度:简单 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 给你一个坐标 coordinates ...

最新文章

  1. 零基础小白学Java难度大不大
  2. mysql可视化工具-navicat的下载和使用
  3. Java ServletContext 详解
  4. Java生产环境下性能监控与调优详解 第8章 JVM字节码与Java代码层调优
  5. mysql滚动条不见了,11-JS处理滚动条
  6. 数据结构与算法笔记(一) 程序性能分析
  7. Cisco Nexus-1000v授权
  8. Express框架的请求处理~非常详细
  9. 【Vijos1659】河蟹王国
  10. 计算机丢失disrupt,disrupt造句
  11. facebuilder免费版_Face Blender(人脸混合器)V2018 最新免费版
  12. 介绍中国传统节日的网页html,介绍中国传统节日
  13. 我们都是被宫崎骏爱过的孩子
  14. SAP中销售项目开票的初步分析
  15. Unity接入穿山甲广告(使用unity插件SDK接入)看这一篇就够了
  16. 关于微擎模块,点击上传图片无反映问题。
  17. Ant Design Vue 动态路由
  18. 自动摘要生成(三):词向量相似度与有效词含量
  19. 2023年上半年软考报考指南~
  20. google map 地理编码API的两种方式

热门文章

  1. 网页上腾讯视频下载mp4格式到本地
  2. MapGIS名词解释
  3. 2018icpc ecfinal 西安游记
  4. HTML基础学习(全)
  5. 机顶盒播放流媒体服务器的文件,IPTV机顶盒的流媒体播放器设计
  6. 解决问题:latex中bib引用顺序不正确,引用顺序和正文不一致
  7. 【图像修复】AOT-GAN《Aggregated Contextual Transformations for High-Resolution Image Inpainting》
  8. 计算机主机故障有哪些,电脑硬件常见故障有哪些
  9. 二阶魔方万能还原公式_二阶魔方复原玩法
  10. 如何搭建一个谷歌广告系列?