算法系列--多源BFS问题

💕"对相爱的人来说,对方的心意,才是最好的房子。"💕
作者:Lvzi
文章主要内容:算法系列–多源BFS问题
在这里插入图片描述

大家好,今天为大家带来的是算法系列--多源BFS问题

前言:
之前我们已经学习过单源的最短路问题,核心就是通过bfs实现来记录最短的路径,解题步骤如下:

  1. 将起点添加进队列–q.add(start)
  2. 一层一层往外扩展(step++)

所谓的多源最短路问题就是有多个起点的最短路问题,如何解决呢?相信大家的第一想法是:不就是多个起点么,每个起点我都做一次单源的最短路问题,再返回结果中最小的不就行了么,这种做法当然是可以的,但是时间复杂度过高,下面讲解第二种方法–超源起点

超源起点就是将所有的起点当做一个起点,以这个点为起点到终点之间的路径就是最短路,从感性上讲为什么这种策略是对的呢?假设我们现在有三个起点,则最短的路径一定是在以这三个点为起点的最短路径之中,则最后求出的一定是最短路径
在这里插入图片描述

这样我们就将多源的最短路问题转化为单源的最短路问题!解法同单源最短路问题,下面是leetocode上比较经典的多源bfs问题

一.01 矩阵(medium)

题目链接:
01 矩阵(medium)
在这里插入图片描述

分析:

转化为从0到1的最短路问题

代码:

// 正难则反的思想
// 将0看作起点,1看做终点  转化为从0-1的最短路问题
class Solution {int[] dx = { 1, -1, 0, 0 };int[] dy = { 0, 0, 1, -1 };public int[][] updateMatrix(int[][] mat) {int m = mat.length, n = mat[0].length;int[][] dist = new int[m][n];Queue<int[]> q = new LinkedList<>();// 将所有起点添加进入队列之中for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (mat[i][j] != 0)dist[i][j] = -1;// 将不是起点的位置全部初始化为-1if (mat[i][j] == 0)q.add(new int[] { i, j });// 将所有的起点添加进队列之中}}// 多源bfswhile (!q.isEmpty()) {int[] t = q.poll();int a = t[0], b = t[1];for (int i = 0; i < 4; i++) {int x = a + dx[i], y = b + dy[i];if (x >= 0 && y >= 0 && x < m && y < n && dist[x][y] == -1) {q.add(new int[] { x, y });dist[x][y] = dist[a][b] + 1;}}}return dist;}
}

总结:
两个小优化的地方:在单源bfs问题之中,我们经常使用三个变量

  • boolean[][] vis:用于标记是否被搜索过
  • int step:用于记录当前的层数(路径长度)
  • int sz:当前层一共有多少个节点

但是在本题中这三个变量都不存在,实际上是通过其他方式来替代了:

  • 将dist数组中不是起点的位置初始化为-1–替代了vis的作用,在判断时,只需判断dist[x][y]是否等于-1即可,如果等于证明没有被搜索过
  • 由于我们在往外扩展的时候是一步一步往外扩展的,dist[a][b]存储的就是走到当前层所需的最小步数,那么以a,b为起点的下一层的所有位置的步数全部都是dist[a][b] + 1的值,不需要通过step来记录路径长度,且也不需要sz来保证是同一层(只要dist[a][b]相同,就是同一层)

二.⻜地的数量

题目链接:⻜地的数量
在这里插入图片描述

分析:

和被围绕的区域类似,这里用的是多源bfs

代码:

// 1.将边界上所有的1添加进入队列
// 2.将所有的联通块(1)标记为0
// 3.统计1的数目,返回即可
class Solution {int[] dx = {1,-1,0,0};int[] dy = {0,0,1,-1};boolean[][] vis;public int numEnclaves(int[][] grid) {int m = grid.length, n = grid[0].length;vis = new boolean[m][n];Queue<int[]> q = new LinkedList<>();// 将边界上所有的1添加进入队列for(int i = 0; i < m; i++) {if(grid[i][0] == 1) q.add(new int[]{i,0});if(grid[i][n - 1] == 1) q.add(new int[]{i,n - 1});}for(int j = 0; j < n; j++) {if(grid[0][j] == 1) q.add(new int[]{0,j});if(grid[m - 1][j] == 1) q.add(new int[]{m - 1, j});}// 多源bfs  将所有的联通块1标记为0while(!q.isEmpty()) {int[] t = q.poll();int a = t[0], b = t[1];grid[a][b] = 0;for(int k = 0; k < 4; k++) {int x = a + dx[k], y = b + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1) {q.add(new int[]{x, y});grid[x][y] = 0;}}}int ret = 0;for(int i = 0; i < m; i++) for(int j = 0; j < n; j++)if(grid[i][j] == 1) ret++;return ret;}
}

三.地图中的最⾼点

题目链接:地图中的最⾼点
在这里插入图片描述
在这里插入图片描述

分析:

多源bfs

代码:

// 和矩阵那道题目相同
class Solution {int[] dx = {1,-1,0,0};int[] dy = {0,0,1,-1};public int[][] highestPeak(int[][] isWater) {int m = isWater.length, n = isWater[0].length;int[][] height = new int[m][n];Queue<int[]> q = new LinkedList<>();for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {if(isWater[i][j] == 1) {q.add(new int[]{i, j});// 将水域添加进队列}else {height[i][j] = - 1;// 陆地置为-1}}}// 多源bfswhile(!q.isEmpty()) {int[] t = q.poll();int a = t[0], b = t[1];for(int k = 0; k < 4; k++) {int x = a + dx[k], y = b + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && height[x][y] == -1) {q.add(new int[]{x, y});height[x][y] = height[a][b] + 1;}}}return height;}
}

四.地图分析

题目链接:地图分析
在这里插入图片描述

分析:

多源bfs + 更新最值
以海洋为起点计算到陆地的最短距离比较困难(无法确定是哪一个海洋)
所以改为以陆地为起点,计算其到海洋的距离

代码:

class Solution {int[] dx = {1,-1,0,0};int[] dy = {0,0,1,-1};public int maxDistance(int[][] grid) {int n = grid.length, ret = 0;int[][] dist = new int[n][n];Queue<int[]> q = new LinkedList<>();boolean flg = false;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {if(grid[i][j] == 1) q.add(new int[]{i, j});// 将陆地当做起点else {dist[i][j] = -1;// 将所有海洋置为-1flg = true;// 存在海洋}}}if(q.size() == 0) return -1;// 全是海洋if(!flg) return -1;// 全是陆地// 多源bfswhile(!q.isEmpty()) {int[] t = q.poll();int a = t[0], b = t[1];for(int k = 0; k < 4; k++) {int x = a + dx[k], y = b + dy[k];if(x >= 0 && y >= 0 && x < n && y < n && dist[x][y] == -1) {q.add(new int[]{x, y});dist[x][y] = dist[a][b] + 1;ret = Math.max(ret, dist[x][y]);// 更新最值}}}return ret;}
}

五.总结

  • 多源bfs最常用的一个思想就是正难则反,这个思想主要用于解决谁是起点,谁是终点的问题
  • 多源bfs问题的代码 比较固定

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/7609.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Toritoise SVN】SVN 怎么忽略文件夹下的所有文件但是不忽略文件夹本身

比如&#xff1a;忽略 Assets\StreamingAssets\LocalAsset文件夹下的所有文件但是不忽略LocalAsset这个文件夹 在TortoiseSVN中&#xff0c;你可以通过以下步骤来修改文件夹的svn:ignore属性&#xff1a; 打开Windows资源管理器&#xff0c;导航到你的工作副本中的Assets\Stre…

VMware虚拟机问题解决方案

1、运行虚拟机系统蓝屏 可能的原因有两个: 1). 虚拟机所在磁盘的空间不足 ; -------> 清理磁盘空间 。 2). 操作系统版本高, 需要适配新版本的Vmware ; ------> 卸载Vmware15版本, 安装Vmware16版本 。 2、卸载VMware的步骤 1&#xff09;卸载已经安装的VMware 从控制面…

8G防火墙,WAF防火墙,可抵御各种恶意请求、恶意机器人、攻击防御

8G防火墙&#xff0c;WAF防火墙&#xff0c;可抵御各种恶意请求、恶意机器人、攻击防御 经过一年多的 beta 测试&#xff0c;8G 防火墙已准备好在生产现场使用。因此&#xff0c;您可以受益于 nG 防火墙&#xff08;又名 nG 黑名单&#xff09;的最新发展提供的强大保护。8G 防…

源代码防泄露可以通过哪些方法实现?七种有效方法分享

在当今数字化时代&#xff0c;访问安全和数据安全成为企业面临的重要挑战。传统的边界防御已经无法满足日益复杂的内网办公环境&#xff0c;层出不穷的攻击手段已经让市场单一的防御手段黔驴技穷。当企业面临越来越复杂的网络威胁和数据泄密风险时&#xff0c;更需要一种综合的…

iOS审核被拒 无法添加以供审核 要开始审核流程,必须提供以下项目

iOS审核被拒 最近有小伙伴反馈上架被拒&#xff0c;提示如下&#xff1a; 无法添加以供审核 要开始审核流程&#xff0c;必须提供以下项目 提交以供审核时遇到意外错误。如果问题仍然存在&#xff0c;请联系我们 后来小伙伴解决方案是&#xff1a;把备案号大写改为小写。 竟…

Ansible自动化工具模块调用与playbook编写

目录 一、Ansible工作机制与特点 &#xff08;一&#xff09;Ansible工作机制 1. 初始化与配置 2. 编写Playbook 3. 调用模块 4. 加密敏感数据 5. 执行Playbook 6. 收集执行结果 7. 错误处理与回滚 8. 反馈与报告 &#xff08;二&#xff09;Ansible 的主要特点包括…

Java并发编程: Synchronized锁升级

文章目录 一、jdk8 markword实现表二、使用工具来查看锁升级 一、jdk8 markword实现表 new -> 偏向锁 -> 轻量级锁&#xff08;自旋锁、自适应自旋锁&#xff09;-> 重量级锁&#xff1a; 偏向锁和轻量级锁都是用户空间完成的。重量级锁是需要向内核申请的。 synchr…

深度学习之基于Matlab神经网络的活体人脸和视频人脸识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 人脸识别技术作为生物识别技术的一种&#xff0c;近年来得到了广泛的关注和应用。与传统的身份认证方…

高素质高学历婚恋相亲交友平台有哪些?分享我的网上找对象成功脱单经历!

尽管觉得在社交软件上找到真爱的可能性很小&#xff0c;但我却时常看到别人成功的案例&#xff0c;这也让我跃跃欲试了。没想到&#xff0c;我真的成功了&#xff01;以下是我亲身使用过的一些方法&#xff0c;在此与大家分享&#xff0c;仅供参考哦&#xff01; &#x1f449;…

新手做抖音小店多久能出单?新手抖音小店出单秘籍!出单教程必看

大家好&#xff0c;我是电商花花。 现阶段还是有很多朋友加入到抖音电商行业&#xff0c;因为抖音小店上还隐藏很多的红利和市场&#xff0c;很多新手开店后第一个问题就是&#xff0c;店铺开通后&#xff0c;一般多久能出单&#xff1f; 多久能出单&#xff0c;其实更看重的…

深入学习和理解Django视图层:处理请求与响应

title: 深入学习和理解Django视图层&#xff1a;处理请求与响应 date: 2024/5/4 17:47:55 updated: 2024/5/4 17:47:55 categories: 后端开发 tags: Django请求处理响应生成模板渲染表单处理中间件异常处理 第一章&#xff1a;Django框架概述 1.1 什么是Django&#xff1f;…

获取波形极值与间距并显示

获取并显示波形的极值与极值间距 1、流程 1、通过signal.find_peaks获取极大值 2、获取极大值下标 3、获取极大值对应的值 4、获取极大值的下标间距(就是隔多远有一个极大值) 5、获取极大值间距的标准差、方差、均值、最大值 6、图形展示波形图并标记极大值2、效果图 3、示…

吴恩达深度学习笔记:深度学习的 实践层面 (Practical aspects of Deep Learning)1.13-1.14

目录 第二门课: 改善深层神经网络&#xff1a;超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第一周&#xff1a;深度学习的 实践层面 (Practical aspects of Deep Learning)1.13 梯度检验&#…

IT 项目管理介绍和资料汇总

IT项目管理到底是什么&#xff1f;是对组织承担的任何信息技术项目的成功监督。IT项目经理负责规划、预算、执行、领导、故障排除和维护这些项目。IT项目经理可能会做的事情包括&#xff1a; 1、硬件安装 2、软件、网站和应用程序开发 3、网络和云计算解决方案的升级和/或推出…

非平衡数据处理-Tomek link算法介绍,代码和实战测评

作者Toby&#xff0c;来源公众号&#xff1a;Python风控模型&#xff0c;非平衡数据处理-Tomek link算法 概述 非平衡数据在金融风控领域、反欺诈客户识别、广告智能推荐和生物医疗中普遍存在。一般而言&#xff0c;不平衡数据正负样本的比例差异极大&#xff0c;如在Kaggle竞…

20240503安装HEVC解码器播放H265格式的8K视频

20240503安装HEVC解码器播放H265格式的8K视频 2024/5/3 9:55 缘起&#xff1a;由于youtube支持8K视频了&#xff0c;想尝尝鲜&#xff01; 主摄像头当然是选择SONY的【夜摄/弱光场景】&#xff0c;根据优选&#xff0c;小米&#xff08;MI&#xff09;13Ultra 最佳了。 在开始播…

jenkins目录下的vue3项目——pnpm install后运行报错——奇葩问题解决

昨天到今天&#xff0c;同事那边遇到一个问题&#xff0c;就是关于vue3vite的项目&#xff0c;在执行了自动打包后&#xff0c;运行代码会提示报错的问题。 报错信息如下&#xff1a; 具体错误信息如下&#xff1a; ERROR 11:28:14 [vite] Pre-transform error: Cannot find …

深入探究TCP/IP协议

一、引言 在信息技术飞速发展的今天&#xff0c;网络已成为人类社会不可或缺的部分。实现网络中计算机相互通信的关键之一便是TCP/IP协议。作为互联网的基础&#xff0c;TCP/IP协议确保了全球范围内的数据交换和信息共享。本文将深入探讨TCP/IP协议的概念、特点、组成、相关协…

C++笔记之调用PCL库显示PCD文件的点云

C++笔记之调用PCL库显示PCD文件的点云 —— 2024-05-05 杭州 code review! 文章目录 C++笔记之调用PCL库显示PCD文件的点云1.运行2.点云pcd文件github下载地址2.main.cpp3.CMakeLists.txt1.运行 2.点云pcd文件github下载地址 https://github.com/luolaihua/point-cloud-data-…

【优选算法】——Leetcode——202—— 快乐数

目录 1.题目 2. 题⽬分析: 3.简单证明&#xff1a; 4. 解法&#xff08;快慢指针&#xff09;&#xff1a; 算法思路&#xff1a; 补充知识&#xff1a;如何求⼀个数n每个位置上的数字的平⽅和。 总结概括 5.代码实现 1.C语言 2.C 1.题目 202. 快乐数 编写一个算法来…