宗亲网站开发,网站前台如何刷新,快速建企业网站,vp代理商网站管理系统可上 欧弟OJ系统 练习华子OD、大厂真题 绿色聊天软件戳 od1441了解算法冲刺训练#xff08;备注【CSDN】否则不通过#xff09; 文章目录 相关推荐阅读一、题目描述二、题目解析三、参考代码PythonJavaC 时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 相关推荐阅读 … 可上 欧弟OJ系统 练习华子OD、大厂真题 绿色聊天软件戳 od1441了解算法冲刺训练备注【CSDN】否则不通过 文章目录 相关推荐阅读一、题目描述二、题目解析三、参考代码PythonJavaC 时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 相关推荐阅读
Dijkstra算法的具体介绍详见单源最短路问题Dijkstra算法详解【经典算法限时免费】
一、题目描述
题目链接https://leetcode.cn/problems/network-delay-time/description/
有 n 个网络节点标记为 1 到 n。
给你一个列表 times表示信号经过 有向 边的传递时间。 times[i] (u(i), v(i), w(i))其中 u(i) 是源节点v(i) 是目标节点 w(i) 是一个信号从源节点传递到目标节点的时间。
现在从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号如果不能使所有节点收到信号返回 -1 。
示例 1 输入times [[2,1,1],[2,3,1],[3,4,1]], n 4, k 2 输出2
示例 2
输入times [[1,2,1]], n 2, k 1 输出1
示例 3
输入times [[1,2,1]], n 2, k 2 输出-1
提示
1 k n 1001 times.length 6000times[i].length 31 u(i), v(i) nu(i) ! v(i)0 w(i) 100所有 (u(i), v(i)) 对都 互不相同即不含重复边
二、题目解析
题目要求计算从源点出发到达所有其他节点的最短路径在所有最短路径中找到最大值。
所以这是一个单源最短路问题可以使用Dijkstra算法来解决计算出dist数组之后取最大值即可。
Dijkstra算法的具体介绍详见单源最短路问题Dijkstra算法详解【经典算法限时免费】
三、参考代码
Python
INF 100000 # 用于表示一个非常大的数作为初始的最短距离class Solution:def networkDelayTime(self, times: List[List[int]], n: int, k: int) - int:# 创建一个邻接表用于存储每个节点的相邻节点及对应的路径权重neighbor_dic defaultdict(list)for a, b, w in times:# 将边 (a - b) 和对应的权重 w 加入邻接表neighbor_dic[a].append((b, w)) # 初始化一个列表 dist用于记录从源节点 k 到每个节点的最短距离# 初始时所有节点的距离都设置为 INF表示尚未访问或不可达dist [INF] * (n1)# 初始化一个最小堆用于在Dijkstra算法中提取当前已知最短路径的节点# 堆中元素是 (当前时间, 当前节点) 元组heap [(0, k)]# 进行Dijkstra类似BFSwhile heap:# 从堆中弹出当前时间最小的节点cur_time, cur_node heappop(heap)# 如果当前节点的已记录最短时间比当前时间更小说明已经找到更优的路径# 因此可以跳过当前节点if cur_time dist[cur_node]:continue# 更新从源节点 k 到当前节点的最短时间dist[cur_node] cur_time# 遍历当前节点的所有相邻节点for next_node, next_weight in neighbor_dic[cur_node]:# 计算通过当前节点到达相邻节点所需的时间next_time cur_time next_weight# 如果通过当前节点到达相邻节点的时间比之前记录的最短时间更短# 则更新相邻节点的最短时间并将其加入堆中以便进一步探索if next_time dist[next_node]:heappush(heap, (next_time, next_node))# 找到从源节点 k 到所有节点的最短路径中的最大值ans max(dist[1:])# 如果最大值小于 INF说明所有节点都可达返回最大值作为网络延迟时间# 否则返回 -1表示有节点无法到达return ans if ans INF else -1Java
import java.util.*;class Solution {static final int INF 100000; // 用于表示一个非常大的数作为初始的最短距离public int networkDelayTime(int[][] times, int n, int k) {// 创建一个邻接表用于存储每个节点的相邻节点及对应的路径权重MapInteger, Listint[] neighbor_dic new HashMap();for (int i 1; i n; i) {neighbor_dic.put(i, new ArrayList());}for (int[] time : times) {int a time[0], b time[1], w time[2];// 将边 (a - b) 和对应的权重 w 加入邻接表neighbor_dic.get(a).add(new int[]{b, w});}// 初始化一个数组 dist用于记录从源节点 k 到每个节点的最短距离// 初始时所有节点的距离都设置为 INF表示尚未访问或不可达int[] dist new int[n 1];Arrays.fill(dist, INF);dist[k] 0; // 源节点到自己的距离为0// 初始化一个最小堆用于在Dijkstra算法中提取当前已知最短路径的节点// 堆中元素是 (当前时间, 当前节点) 元组PriorityQueueint[] heap new PriorityQueue(Comparator.comparingInt(a - a[0]));heap.offer(new int[]{0, k});// 进行Dijkstra类似BFSwhile (!heap.isEmpty()) {// 从堆中弹出当前时间最小的节点int[] cur heap.poll();int cur_time cur[0], cur_node cur[1];// 如果当前节点的已记录最短时间比当前时间更小说明已经找到更优的路径// 因此可以跳过当前节点if (cur_time dist[cur_node]) {continue;}// 遍历当前节点的所有相邻节点for (int[] neighbor : neighbor_dic.getOrDefault(cur_node, new ArrayList())) {int next_node neighbor[0], next_weight neighbor[1];// 计算通过当前节点到达相邻节点所需的时间int next_time cur_time next_weight;// 如果通过当前节点到达相邻节点的时间比之前记录的最短时间更短// 则更新相邻节点的最短时间并将其加入堆中以便进一步探索if (next_time dist[next_node]) {dist[next_node] next_time;heap.offer(new int[]{next_time, next_node});}}}// 找到从源节点 k 到所有节点的最短路径中的最大值int ans Arrays.stream(dist).skip(1).max().getAsInt();// 如果最大值小于 INF说明所有节点都可达返回最大值作为网络延迟时间// 否则返回 -1表示有节点无法到达return ans INF ? ans : -1;}
}C
int INF 100000; // 用于表示一个非常大的数作为初始的最短距离class Solution {
public:int networkDelayTime(vectorvectorint times, int n, int k) {// 创建一个邻接表用于存储每个节点的相邻节点及对应的路径权重unordered_mapint, vectorpairint, int neighbor_dic;for (const auto time : times) {int a time[0], b time[1], w time[2];// 将边 (a - b) 和对应的权重 w 加入邻接表neighbor_dic[a].push_back({b, w});}// 初始化一个列表 dist用于记录从源节点 k 到每个节点的最短距离// 初始时所有节点的距离都设置为 INF表示尚未访问或不可达vectorint dist(n 1, INF);dist[k] 0; // 起点距离为0// 初始化一个最小堆用于在Dijkstra算法中提取当前已知最短路径的节点// 堆中元素是 (当前时间, 当前节点) 元组priority_queuepairint, int, vectorpairint, int, greaterpairint, int heap;heap.push({0, k});// 进行Dijkstra算法类似BFSwhile (!heap.empty()) {// 从堆中弹出当前时间最小的节点auto [cur_time, cur_node] heap.top();heap.pop();// 如果当前节点的已记录最短时间比当前时间更小说明已经找到更优的路径// 因此可以跳过当前节点if (cur_time dist[cur_node]) {continue;}// 遍历当前节点的所有相邻节点for (auto [next_node, next_weight] : neighbor_dic[cur_node]) {// 计算通过当前节点到达相邻节点所需的时间int next_time cur_time next_weight;// 如果通过当前节点到达相邻节点的时间比之前记录的最短时间更短// 则更新相邻节点的最短时间并将其加入堆中以便进一步探索if (next_time dist[next_node]) {dist[next_node] next_time;heap.push({next_time, next_node});}}}// 找到从源节点 k 到所有节点的最短路径中的最大值int ans *max_element(dist.begin() 1, dist.end());// 如果最大值小于 INF说明所有节点都可达返回最大值作为网络延迟时间// 否则返回 -1表示有节点无法到达return ans INF ? ans : -1;}
};时空复杂度
时间复杂度O((VE)logV)。
空间复杂度O(VE)。
其中V是节点数E是边数。 华为OD算法/大厂面试高频题算法练习冲刺训练 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名目前已服务300同学成功上岸 课程讲师为全网50w粉丝编程博主吴师兄学算法 以及小红书头部编程博主闭着眼睛学数理化 每期人数维持在20人内保证能够最大限度地满足到每一个同学的需求达到和1v1同样的学习效果 60天陪伴式学习40直播课时300动画图解视频300LeetCode经典题200华为OD真题/大厂真题还有简历修改、模拟面试、专属HR对接将为你解锁 可上全网独家的欧弟OJ系统练习华子OD、大厂真题 可查看链接 大厂真题汇总 OD真题汇总(持续更新) 绿色聊天软件戳 od1336了解更多