【LeetCode】公交路线 [H](宽度优先遍历)
815. 公交路线 - 力扣(LeetCode)
一、题目
给你一个数组 routes ,表示一系列公交线路,其中每个 routes[i] 表示一条公交线路,第 i 辆公交车将会在上面循环行驶。
例如,路线 routes[0] = [1, 5, 7] 表示第 0 辆公交车会一直按序列 1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> ... 这样的车站路线行驶。
现在从 source 车站出发(初始时不在公交车上),要前往 target 车站。 期间仅可乘坐公交车。
求出 最少乘坐的公交车数量 。如果不可能到达终点车站,返回 -1 。
示例 1:
输入:routes = [[1,2,7],[3,6,7]], source = 1, target = 6
输出:2
解释:最优策略是先乘坐第一辆公交车到达车站 7 , 然后换乘第二辆公交车到车站 6 。
示例 2:
输入:routes = [[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12
输出:-1
提示:
- 1 <= routes.length <= 500.
- 1 <= routes[i].length <= 105
- routes[i] 中的所有值 互不相同
- sum(routes[i].length) <= 105
- 0 <= routes[i][j] < 106
- 0 <= source, target < 106
二、代码
class Solution {// routes数组表示每一种公交线路包括哪些公交站// 0 : [1,3,7,0] 0号公交线路包括1、3、7、0这四个公交站// 1 : [7,9,6,2]// ....// 返回:返回换乘次数+1 -> 返回一共坐了多少次公交。public int numBusesToDestination(int[][] routes, int source, int target) {// 如果起点和目标一致,直接返回0if (source == target) {return 0;}// 全部的公交线路数int n = routes.length;// key : 车站// value : list -> 该车站被哪些线路拥有 list中存储的公交线路编号HashMap<Integer, ArrayList<Integer>> map = new HashMap<>();// 根据routes数组构造出mapfor (int i = 0; i < n; i++) {// 遍历每一条路线下的每一个车站for (int station : routes[i]) {// 将每一个车站所在的线路编号加入到map中这个车站对应的value中// 如果这个车站还没有创建map,就手动创建一个if (!map.containsKey(station)) {map.put(station, new ArrayList<Integer>());}// station车站被i号路线拥有map.get(station).add(i);}}// 至此,通过map就可以快速取出一个车站可以通往哪些公交路线// 宽度优先遍历用的队列,里面加入的是公交线路编号ArrayList<Integer> queue = new ArrayList<>();// 标记路线是否已经被宽度优先遍历过了boolean[] set = new boolean[n];// 将起点能够走到的公交线路都取出来,这些公交线路就是我们一开始能走的路线for (int route : map.get(source)) {// 将公交线路加入到队列中queue.add(route);// 将这个线路标记为true,表示已经遍历到了set[route] = true;}// 记录换乘次数int cnt = 0;// 开始深度优先遍历,每次就直接把一层的都遍历出来while (!queue.isEmpty()) {// 记录下一层宽度遍历的路线列表ArrayList<Integer> nextRoutes = new ArrayList<>();// 遍历当前队列中的所有线路,表示当前能走到的线路for (Integer route : queue) {// 获取这些线路包括车站int[] stations = routes[route];// 遍历每一条线路的所有车站for (int station : stations) {// 如果这个车站就是终点,直接返回换乘次数+1if (station == target) {// 之所以加1,是因为cnt统计的是换乘次数,题目要求要返回乘坐公交车的数量,所以要加1return cnt + 1;}// 通过这个车站再去找下一次换乘能走到的路线由哪些。利用之前构造的map结构找for (int nextRoute : map.get(station)) {// 保证这个路线没有被遍历过if (!set[nextRoute]) {// 将这个路线加入到nextRoutes中,供下一层遍历使用nextRoutes.add(nextRoute);// 将这个路线标记为已经遍历到了set[nextRoute] = true;}}}}// 每遍历一层,换成次数就加1cnt++;// 将下一层的路线列表赋值给queue,作为下一轮遍历过程中可以走到的路线列表queue = nextRoutes;}// 不能走到就返回-1return -1;}
}
三、解题思路
先把每个站点拥有哪些线路标好,这个线路就是指的routes[i]数组的下标,把每个站点和一个数字i绑定,那么就可以通过这个数字i,直接找到routes[i],这个就是这个站点所在的线路。
从source出发,先遍历source这个站点的所有所在路线,也就遍历出了第一层1、2、3这三条路线,表示source这个站点,下一步可以走到1、2、3这三条公交线路中(公交线路本身也是包含了多个站点的),我们也就知道了从source这个点,只换乘一次能到达的全新的线路有哪些,将这些路线加入到队列中,并且再去遍历一下这三条线路所经过的所有车站,就能够得到只换乘一次,能到达的所有车站有哪些,再通过这些车站,去找下一次换乘能到达的路线有哪些,将这些新路线存储到nextRoute数组中,供下一层宽度遍历时使用。
在宽度优先遍历过程中,每遍历一层,也就是换成次数加1,因为每一层的遍历就是从一个站点到另外的线路上,期间就是只需要换乘一次。两条线路虽然都有多个站点,但是只有两辆不同的车而已。
遍历完第一层后,下一层的宽度优先遍历就是在用相同的方法,以nextRoute数组中上一轮换乘一次可以来到的全新路线为起点,再遍历一下每一个路线只换乘一次就能到达的全新线路,然后再去看这些全新线路都能经过的车站都找出来,通过这些车站再去找下一轮换乘一次能到达的全新路线有哪些,存储到nextRoute数组中,在下层的遍历时就会将这些一次换乘就能走到的全新路线加入到队列中。整个流程就是每一次都直接把一整层遍历出来,完成深度优先遍历。
因为每次都是向外扩一层,按照宽度优先遍历的顺序来遍历,所以只要是在这个过程中找到了目的地target站点,那么记录的换乘次数一定是最少的。
相关文章:
【LeetCode】公交路线 [H](宽度优先遍历)
815. 公交路线 - 力扣(LeetCode) 一、题目 给你一个数组 routes ,表示一系列公交线路,其中每个 routes[i] 表示一条公交线路,第 i 辆公交车将会在上面循环行驶。 例如,路线 routes[0] [1, 5, 7] 表示第 …...
报表生成器 FastReport .Net 用户指南 2023(十):Band的属性
FastReport .Net是一款全功能的Windows Forms、ASP.NET和MVC报表分析解决方案,使用FastReport .NET可以创建独立于应用程序的.NET报表,同时FastReport .Net支持中文、英语等14种语言,可以让你的产品保证真正的国际性。 FastReport.NET官方版…...
DAMA数据管理知识体系指南之文档和内容管理
第10章 文档和内容管理 10.1 简介 文档和内容管理是对存储在关系数据库以外的信息的采集、存储、访问以及使用的控制活动。文档和内容管理的侧重点在完整性和访问控制上。因此,它与关系数据库的数据操作管理大致相同。由于多数非结构化数据与存储在结构化文件中的…...
C++入门:数据结构
C/C 数组允许定义可存储相同类型数据项的变量,但是结构是 C 中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。结构用于表示一条记录,假设您想要跟踪图书馆中书本的动态,您可能需要跟踪每本书的下列属性&#x…...
C语言实现烟花表白,内含源码!!
虽然现在看烟花有一定难度,但代码式烟花可以随时随地看! 烟花的代码很多,实际上是可以用 Python、HTML5 等语言写烟花,但今天主要想和大家分享用C语言写的烟花代码,非常细致和实用。 同学们一定要亲自敲一遍…...
虚拟机安装CentOS 7(带界面)
目录 一、虚拟机安装CentOS 7(带界面) 1、打开下好的VMware,点击创建虚拟机 2、下一步 3、点击下一步 4、选择Linux,ContOS7,点击下一步 5、修改虚拟机名称和路径 6、下一步 7、点击自定义硬件 8、设置虚拟机大…...
Java测试——selenium具体操作
selenium的前置准备工作可以参考我之前的博客:Java测试——selenium的安装与使用教程 这篇博客讲解一下selenium的常见操作 先创建driver ChromeDriver driver new ChromeDriver();输入网址 driver.get("https://www.baidu.com");常见操作 查找元素…...
电子器件系列32:逻辑与门芯片74LS11
一、编码规则 先看看这个代码的意思:74LS11 74是一个系列(74 表示为工作温度范围,74: 0 ~ 70度。) ls的意思就是工艺类型(Bipolar(双极)工艺) 11是代码 什么是74系列逻辑芯片? - 知乎 什么是…...
LeetCode-101. 对称二叉树
目录题目分析递归法题目来源 101. 对称二叉树 题目分析 首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点! 对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一…...
使用intlinprog求解指派问题MATLAB代码分享
% 输入指派矩阵C [3 8 2 10 3;8 7 2 9 7;6 4 2 7 5;8 4 2 3 5;9 10 6 9 10];f C(:); %生成一个列向量,作为目标函数系数,matlab默认以列排序[m,n] size(C);Aeq zeros(2*n,n*n); %2*n个等式约束,n*n个变量for i 1:n %这里先生成的是后5个…...
Spark On YARN时指定Python版本
坑很多,直接上兼容性最佳的命令,将python包上传到hdfs或者file:/home/xx/(此处无多余的/) # client 模式 $SPARK_HOME/spark-submit \ --master yarn \ --deploy-mode client \ --num-executors 2 \ --conf "spark.yarn.dist.archives<Python包…...
[数据库]库的增删改查
●🧑个人主页:你帅你先说. ●📃欢迎点赞👍关注💡收藏💖 ●📖既选择了远方,便只顾风雨兼程。 ●🤟欢迎大家有问题随时私信我! ●🧐版权:本文由[你帅…...
Wine零知识学习1 —— 介绍
一、什么是Wine Wine是“Wine Is Not an Emulator” 的首字母缩写,是一个能够在多种POSIX-compliant操作系统(诸如Linux、macOS及BSD等)上运行 Windows 应用的兼容层。Wine不像虚拟机或者模拟器那样模仿内部的Windows逻辑,而是將…...
设计模式--建造者模式 builder
设计模式--建造者模式 builder)建造者模式简介建造者模式--小例子(电脑购买)1.产品类2.抽象构建者3.实体构建类4.指导者类5.客户端测试类小结建造者模式简介 建造者模式有四个角色,概念划分如下: Product : 产品类&a…...
终于周末啦,继续来总结一下Python的一些知识点啦
目录 Python概念梳理 常见概念梳理 Python经典判断题 判断题 选择题 Python概念梳理 常见概念梳理 Python中,不仅仅变量的值是可以变化的,类型也是可以随时变化的 1、Python的变量必须初始化否则提示 is not defined 2、if、while中定义的变量在…...
CUDA By Example(八)——流
文章目录页锁定主机内存可分页内存函数页锁定内存函数CUDA流使用单个CUDA流使用多个CUDA流GPU的工作调度机制高效地使用多个CUDA流遇到的问题(未解决)页锁定主机内存 在之前的各个示例中,都是通过 cudaMalloc() 在GPU上分配内存,以及通过标准的C库函数 …...
02- pandas 数据库 (数据库)
pandas 数据库重点: pandas 的主要数据结构: Series (一维数据)与 DataFrame (二维数据)。 pd.DataFrame(data np.random.randint(0,151,size (5,3)), # 生成pandas数据 index [Danial,Brandon,softpo,Ella,Cindy], # 行索引 …...
less常用语法总结
CSS预处理器 CSS 预处理器是什么?一般来说,它们基于 CSS 扩展了一套属于自己的 DSL,来解决我们书写 CSS 时难以解决的问题: 语法不够强大,比如无法嵌套书写导致模块化开发中需要书写很多重复的选择器;没有变量和合理的样式复用机制,使得逻辑上相关的属性值必须以字面量…...
DHCP Relay中继实验
DHCP Relay实验拓扑图设备配置结果验证拓扑图 要求PC1按照地址池自动分配,而PC要求分配固定的地址,网段信息已经在图中进行标明。 设备配置 AR1: AR1作为DHCP Server基本配置跟DHCP Server没区别,不过要加一条静态路由ÿ…...
“1+1>2”!《我要投资》与天际汽车再度“双向奔赴”!
文|螳螂观察 作者| 图霖 胡海泉老师重磅回归、创始人现场真情告白……新一季的《我要投资》,不仅维持了往季在专业度上的高水准,也贡献了不少高话题度的“出圈”时刻。 在竞争激烈的的综艺节目竞技场,能举办数季的节目,往往都是…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
