news 2026/8/5 21:11:22

最短路题目:网络延迟时间

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
最短路题目:网络延迟时间

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 前言
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:网络延迟时间

出处:743. 网络延迟时间

难度

5 级

题目描述

要求

给定一个由n \texttt{n}n个结点组成的网络,结点编号为1 \texttt{1}1n \texttt{n}n。另外给定一个表示信号经过有向边的传递时间的列表times \texttt{times}timestimes[i] = (u i , v i , w i ) \texttt{times[i] = (u}_\texttt{i}\texttt{, v}_\texttt{i}\texttt{, w}_\texttt{i}\texttt{)}times[i] = (ui, vi, wi),其中u i \texttt{u}_\texttt{i}ui是源结点,v i \texttt{v}_\texttt{i}vi是目标结点,w i \texttt{w}_\texttt{i}wi是一个信号从源结点传递到目标结点的时间。

从给定结点k \texttt{k}k发出一个信号。返回使所有n \texttt{n}n个结点都收到信号的最少时间。如果不能使所有n \texttt{n}n个结点都收到信号,返回-1 \texttt{-1}-1

示例

示例 1:

输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2 \texttt{times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2}times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
输出:2 \texttt{2}2

示例 2:

输入:times = [[1,2,1]], n = 2, k = 1 \texttt{times = [[1,2,1]], n = 2, k = 1}times = [[1,2,1]], n = 2, k = 1
输出:1 \texttt{1}1

示例 3:

输入:times = [[1,2,1]], n = 2, k = 2 \texttt{times = [[1,2,1]], n = 2, k = 2}times = [[1,2,1]], n = 2, k = 2
输出:-1 \texttt{-1}-1

数据范围

  • 1 ≤ k ≤ n ≤ 100 \texttt{1} \le \texttt{k} \le \texttt{n} \le \texttt{100}1kn100
  • 1 ≤ times.length ≤ 6000 \texttt{1} \le \texttt{times.length} \le \texttt{6000}1times.length6000
  • times[i].length = 3 \texttt{times[i].length} = \texttt{3}times[i].length=3
  • 1 ≤ u i , v i ≤ n \texttt{1} \le \texttt{u}_\texttt{i}\texttt{, v}_\texttt{i} \le \texttt{n}1ui, vin
  • u i ≠ v i \texttt{u}_\texttt{i} \ne \texttt{v}_\texttt{i}ui=vi
  • 0 ≤ w i ≤ 100 \texttt{0} \le \texttt{w}_\texttt{i} \le \texttt{100}0wi100
  • 所有(u i , v i ) \texttt{(u}_\texttt{i}\texttt{, v}_\texttt{i}\texttt{)}(ui, vi)各不相同(即不含重复边)

前言

这道题要求计算从网络中的给定结点k kk发出信号到所有结点都收到信号的最少时间。由于给定的网络是有向带权图,因此这道题等价于计算从结点k kk到所有结点的最短路径权重。

单源最短路径算法包括 Bellman-Ford 算法和 Dijkstra 算法。这道题中,每条边的权重都非负,因此 Bellman-Ford 算法和 Dijkstra 算法都可以使用。

解法一

思路和算法

当图中有n nn个结点时,Bellman-Ford 算法的做法是对图中的所有边执行n − 1 n - 1n1次遍历,得到从结点k kk到每个结点的最短路径权重。

创建数组receiveTimes \textit{receiveTimes}receiveTimes记录从结点k kk到每个结点的最短路径权重,初始时receiveTimes [ k ] = 0 \textit{receiveTimes}[k] = 0receiveTimes[k]=0receiveTimes \textit{receiveTimes}receiveTimes中的其余元素都是∞ \infty

将遍历到的边的起点、终点和权重分别记为start \textit{start}startend \textit{end}endweight \textit{weight}weight,如果receiveTimes [ start ] ≠ ∞ \textit{receiveTimes}[\textit{start}] \ne \inftyreceiveTimes[start]=receiveTimes [ end ] > receiveTimes [ start ] + weight \textit{receiveTimes}[\textit{end}] > \textit{receiveTimes}[\textit{start}] + \textit{weight}receiveTimes[end]>receiveTimes[start]+weight,则将receiveTimes [ end ] \textit{receiveTimes}[\textit{end}]receiveTimes[end]的值更新为receiveTimes [ start ] + weight \textit{receiveTimes}[\textit{start}] + \textit{weight}receiveTimes[start]+weight

初始时可以确定结点k kk对应的最短路径权重是0 00。每一次遍历之后,可以确定图中的一个结点对应的最短路径权重,n − 1 n - 1n1次遍历之后即可得到从源结点到每个结点的最短路径权重。

如果所有结点的最短路径权重都不是∞ \infty,则所有结点都能收到信号,返回最短路径权重的最大值。如果存在结点的最短路径权重是∞ \infty,则∞ \infty对应的结点不能收到信号,返回− 1 -11

代码

classSolution{publicintnetworkDelayTime(int[][]times,intn,intk){int[]receiveTimes=newint[n+1];Arrays.fill(receiveTimes,Integer.MAX_VALUE);receiveTimes[0]=receiveTimes[k]=0;for(inti=1;i<n;i++){for(int[]edge:times){intstart=edge[0],end=edge[1],weight=edge[2];if(receiveTimes[start]!=Integer.MAX_VALUE&&receiveTimes[end]>receiveTimes[start]+weight){receiveTimes[end]=receiveTimes[start]+weight;}}}intmaxTime=Arrays.stream(receiveTimes).max().getAsInt();returnmaxTime!=Integer.MAX_VALUE?maxTime:-1;}}

复杂度分析

  • 时间复杂度:O ( n m ) O(nm)O(nm),其中n nn是图中的结点数,m mm是图中的边数。Bellman-Ford 算法的时间复杂度是O ( n m ) O(nm)O(nm),计算所有结点的最短路径权重需要O ( n ) O(n)O(n)的时间得到使所有结点都收到信号的最少时间,因此时间复杂度是O ( n m ) O(nm)O(nm)

  • 空间复杂度:O ( n ) O(n)O(n),其中n nn是图中的结点数。记录从结点k kk到每个结点的最短路径权重需要O ( n ) O(n)O(n)的空间。

解法二

思路和算法

当图中有n nn个结点时,Dijkstra 算法的做法是对图中的结点执行n nn次循环,得到从源结点到每个结点的最短路径权重。

每次循环时,从尚未确定最短路径权重的结点中找到最短路径权重最小的结点,将该结点的状态更新为确定最短路径权重,并使用该结点的最短路径权重更新该结点的所有后继结点的最短路径权重。由于每次循环都能确定一个结点的最短路径权重,因此经过n nn次循环之后即可得到每个结点的最短路径权重。

寻找最短路径权重最小的结点有两种做法,第一种做法是枚举所有尚未确定最短路径权重的结点,第二种做法是维护小根堆。

为了方便处理,需要首先将边数组转换成邻接结点列表的形式,转换后可以在O ( 1 ) O(1)O(1)时间获得一个结点的全部相邻结点。

代码

下面的代码为基于枚举实现。

classSolution{publicintnetworkDelayTime(int[][]times,intn,intk){List<int[]>[]adjacentArr=newList[n+1];for(inti=0;i<=n;i++){adjacentArr[i]=newArrayList<int[]>();}for(int[]edge:times){intstart=edge[0],end=edge[1],weight=edge[2];adjacentArr[start].add(newint[]{end,weight});}int[]receiveTimes=newint[n+1];Arrays.fill(receiveTimes,Integer.MAX_VALUE);receiveTimes[0]=receiveTimes[k]=0;boolean[]visited=newboolean[n+1];for(inti=1;i<=n;i++){intcurr=-1;for(intj=1;j<=n;j++){if(!visited[j]&&(curr<0||receiveTimes[curr]>receiveTimes[j])){curr=j;}}visited[curr]=true;for(int[]adjacent:adjacentArr[curr]){intnext=adjacent[0],weight=adjacent[1];receiveTimes[next]=Math.min(receiveTimes[next],receiveTimes[curr]+weight);}}intmaxTime=Arrays.stream(receiveTimes).max().getAsInt();returnmaxTime!=Integer.MAX_VALUE?maxTime:-1;}}

下面的代码为基于小根堆实现。

classSolution{publicintnetworkDelayTime(int[][]times,intn,intk){List<int[]>[]adjacentArr=newList[n+1];for(inti=0;i<=n;i++){adjacentArr[i]=newArrayList<int[]>();}for(int[]edge:times){intstart=edge[0],end=edge[1],weight=edge[2];adjacentArr[start].add(newint[]{end,weight});}int[]receiveTimes=newint[n+1];Arrays.fill(receiveTimes,Integer.MAX_VALUE);receiveTimes[0]=receiveTimes[k]=0;PriorityQueue<int[]>pq=newPriorityQueue<int[]>((a,b)->a[1]-b[1]);pq.offer(newint[]{k,0});while(!pq.isEmpty()){int[]pair=pq.poll();intcurr=pair[0],receiveTime=pair[1];if(receiveTimes[curr]<receiveTime){continue;}for(int[]adjacent:adjacentArr[curr]){intnext=adjacent[0],weight=adjacent[1];if(receiveTimes[next]>receiveTime+weight){receiveTimes[next]=receiveTime+weight;pq.offer(newint[]{next,receiveTimes[next]});}}}intmaxTime=Arrays.stream(receiveTimes).max().getAsInt();returnmaxTime!=Integer.MAX_VALUE?maxTime:-1;}}

复杂度分析

  • 时间复杂度:O ( n 2 + m ) O(n^2 + m)O(n2+m)O ( ( n + m ) log ⁡ n ) O((n + m) \log n)O((n+m)logn),其中n nn是图中的结点数,m mm是图中的边数。将边数组转换成邻接结点列表需要O ( n + m ) O(n + m)O(n+m)的时间,Dijkstra 算法的时间复杂度取决于实现方式,基于枚举实现的时间复杂度是O ( n 2 ) O(n^2)O(n2),基于小根堆实现的时间复杂度是O ( ( n + m ) log ⁡ n ) O((n + m) \log n)O((n+m)logn),计算所有结点的最短路径权重需要O ( n ) O(n)O(n)的时间得到使所有结点都收到信号的最少时间,因此时间复杂度是O ( n 2 + m ) O(n^2 + m)O(n2+m)O ( ( n + m ) log ⁡ n ) O((n + m) \log n)O((n+m)logn)

  • 空间复杂度:O ( n + m ) O(n + m)O(n+m),其中n nn是图中的结点数,m mm是图中的边数。邻接结点列表需要O ( n + m ) O(n + m)O(n+m)的空间,记录从结点k kk到每个结点的最短路径需要O ( n ) O(n)O(n)的空间,记录每个结点是否访问过的数组和优先队列需要O ( n ) O(n)O(n)的空间,因此空间复杂度是O ( n + m ) O(n + m)O(n+m)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/5 21:10:57

洛雪音乐音源:重新定义免费高品质音乐体验

洛雪音乐音源&#xff1a;重新定义免费高品质音乐体验 【免费下载链接】lxmusic- lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/gh_mirrors/lx/lxmusic- 在数字音乐付费订阅成为主流的今天&#xff0c;你是否还在为寻找免费又高质量的音乐资源而烦…

作者头像 李华
网站建设 2026/8/5 21:10:47

哈工大近世代数期末复习

近世代数是抽象代数的一个分支,是计算机科学和人工智能大数据的基础. 本文内容有点长,大家可以通过index来跳转到想要看的章节,第十章的总结在我的主页里下载 1.代数系 半群:满足结合律的代数系 交换半群:满足交换律的半群 群&#xff1a;判定方法有两种 method1 有单…

作者头像 李华
网站建设 2026/8/5 21:06:32

LivePortrait:从静态肖像到动态表情的AI魔法

LivePortrait&#xff1a;从静态肖像到动态表情的AI魔法 【免费下载链接】LivePortrait Bring portraits to life! 项目地址: https://gitcode.com/GitHub_Trending/li/LivePortrait 想象一下&#xff0c;你有一张静态的肖像照片&#xff0c;只需一个驱动视频或简单的表…

作者头像 李华
网站建设 2026/8/5 20:58:43

TestDisk数据恢复工具:免费开源的数据拯救专家

TestDisk数据恢复工具&#xff1a;免费开源的数据拯救专家 【免费下载链接】testdisk TestDisk & PhotoRec 项目地址: https://gitcode.com/gh_mirrors/te/testdisk 你是否曾因误删重要文件而焦虑不已&#xff1f;是否遇到过硬盘分区神秘消失的困境&#xff1f;别担…

作者头像 李华
网站建设 2026/8/5 20:58:07

从0到1开发FIDO2应用:基于libfido2的认证流程设计与最佳实践

从0到1开发FIDO2应用&#xff1a;基于libfido2的认证流程设计与最佳实践 【免费下载链接】libfido2 Provides library functionality for FIDO2, including communication with a device over USB or NFC. 项目地址: https://gitcode.com/gh_mirrors/li/libfido2 libfid…

作者头像 李华