【Py/Java/C++三种语言详解】LeetCode743、网络延迟时间【单源最短路问题Djikstra算法】

news2025/1/11 18:41:35

可上 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳 od1441了解算法冲刺训练(备注【CSDN】否则不通过)

文章目录

  • 相关推荐阅读
    • 一、题目描述
    • 二、题目解析
    • 三、参考代码
      • Python
      • Java
      • C++
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

相关推荐阅读

  • Dijkstra算法的具体介绍详见单源最短路问题:Dijkstra算法详解【经典算法,限时免费】)

一、题目描述

题目链接:https://leetcode.cn/problems/network-delay-time/description/

n 个网络节点,标记为 1n

给你一个列表 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 <= 100
  • 1 <= times.length <= 6000
  • times[i].length == 3
  • 1 <= u(i), v(i) <= n
  • u(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] * (n+1)

        # 初始化一个最小堆,用于在Dijkstra算法中提取当前已知最短路径的节点
        # 堆中元素是 (当前时间, 当前节点) 元组
        heap = [(0, k)]

        # 进行Dijkstra(类似BFS)
        while 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 -1

Java

import java.util.*;

class Solution {
    static final int INF = 100000;  // 用于表示一个非常大的数,作为初始的最短距离

    public int networkDelayTime(int[][] times, int n, int k) {
        // 创建一个邻接表,用于存储每个节点的相邻节点及对应的路径权重
        Map<Integer, List<int[]>> 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算法中提取当前已知最短路径的节点
        // 堆中元素是 (当前时间, 当前节点) 元组
        PriorityQueue<int[]> heap = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
        heap.offer(new int[]{0, k});

        // 进行Dijkstra(类似BFS)
        while (!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(vector<vector<int>>& times, int n, int k) {
        // 创建一个邻接表,用于存储每个节点的相邻节点及对应的路径权重
        unordered_map<int, vector<pair<int, 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(表示尚未访问或不可达)
        vector<int> dist(n + 1, INF);
        dist[k] = 0;  // 起点距离为0

        // 初始化一个最小堆,用于在Dijkstra算法中提取当前已知最短路径的节点
        // 堆中元素是 (当前时间, 当前节点) 元组
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> heap;
        heap.push({0, k});

        // 进行Dijkstra算法(类似BFS)
        while (!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((V+E)logV)

空间复杂度:O(V+E)

其中V是节点数,E是边数。


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务300+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

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

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

相关文章

Java入门:06.Java中的方法--进阶01

1 JVM中方法的执行过程 1.1 JVM内存模型 在java程序的执行过程中会产生一些数据&#xff0c;这些数据将会存在jvm内存中。 JVM将内存分成了不同的逻辑区域&#xff0c;存储不同含义&#xff08;类别&#xff09;的数据 JVM内存模型有5种 方法区 &#xff1a; 存储类信息 堆…

初识redis:Set类型

Set有很多种含义&#xff0c;比如集合&#xff0c;比如设置&#xff08;和get相对应&#xff09;。 在这里我们说的set是指的redis中的集合&#xff0c;并且这里的集合是无序的&#xff0c;和之前的list是对应的。 List &#xff1a; [1,2,3] 和 [2,1,3] 是两个不同的listSe…

hbase-manager图形化界面的安装与配置

相关资料下载 夸克网盘分享 1、上传项目到linux上 解压&#xff1a; 切换到conf目录下&#xff1a;/opt/installs/hbase-manager-2.0.8-hbase-2.x/conf/ 2、修改数据库配置信息 application-druid.yml 3、创建hbase-manager数据库(注意字符集编码)&#xff0c;导入数据库脚本…

飞鸟物联平台数字化解决方案:全方位提升OEM厂商销售、售后服务能力

自从OEM厂商把设备销售给终端客户&#xff0c;这笔交易就到此为止了。一旦目标行业出现下行趋势&#xff0c;订单和利润往往难以为继&#xff0c;OEM厂商往往遭受着其特有的三重考验&#xff1a;设备状况不透明、设备维保成本高、终端客户粘性低。这些挑战如同“三害”压得OEM厂…

AI搜索产品:秘塔、天工、perplexity、felo、360AI搜索

1、秘塔 https://metaso.cn/ 2、天工 https://www.tiangong.cn/ 3、perplexity https://www.perplexity.ai/ 4、Felo https://felo.ai/search 5、360ai搜索 https://www.sou.com/

洛谷P3865.ST表

洛谷P3865.ST表 i的取值为[1,n−2j1]从而推出j的取值为 j < lg[n]找区间最值时&#xff1a; 要找一段起始点L的可覆盖[L,R]的区间&#xff0c;即L 2k - 1 < R –> k < lg[R-L1] (区间长度)同时起点为 D R - 2k 1 (起始点)即f[D][k] #include <bits/stdc.…

12.1.案例专题-数据流图

文章目录 数据流图结构化语言描述示例 练习题2020年真题2021年上真题 数据流图 数据流图DFD基本图形元素&#xff1a;外部实体、加工、数据存储、数据流。 数据流&#xff1a;由一组固定成分的数据组成&#xff0c;表示数据的流向。在DFD中&#xff0c;数据流的流向必须经过…

IP进程间的通信方式以及不同主机间的通信方式

一&#xff0c;IP进程间的通信方式 共享内存&#xff08;最高效&#xff09; 1.是一块内核的预留空间 2.避免了用户空间到内核空间的数据拷贝 1.产生key:ftok函数 功能&#xff1a;将pathname和pid_id转化为key 参数&#xff1a;(路径名&#xff0c;A) 返回值&#xff1…

Java并发类API——ExecutorService

1.ExecutorService概述 ExecutorService 是 Java 并发库中一个非常重要的接口&#xff0c;它提供了一种管理和控制线程执行的方法。ExecutorService 是 Executor 接口的扩展&#xff0c;除了 Executor 提供的基础任务执行功能之外&#xff0c;ExecutorService 提供了更强大的功…

如何用Python构建高校爬虫与k-means算法实现专业评分可视化分析

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

工业互联网与大数据实训室解决方案

一、引言 1.1 工业互联网与大数据的重要性 工业互联网作为新一代信息技术与制造业深度融合的产物&#xff0c;正在全球范围内推动着制造业的数字化、网络化、智能化转型。它通过连接机器、物料、人和信息系统&#xff0c;实现数据的全面感知、动态传输和智能分析&#xff0c;…

白酒与素食:健康与美味的双重享受

在美食的世界里&#xff0c;白酒与素食的搭配仿佛是一场跨界的盛宴。豪迈白酒&#xff08;HOMANLISM&#xff09;的醇香与精致素食的清新&#xff0c;在不经意间交织出了一幅美妙的画卷&#xff0c;让人在品味中感受到健康与美味的双重享受。 素食&#xff0c;以其清淡、自然的…

Verilog刷题笔记54

题目&#xff1a; Fsm serialdp See also: Serial receiver and datapath We want to add parity checking to the serial receiver. Parity checking adds one extra bit after each data byte. We will use odd parity, where the number of 1s in the 9 bits received must…

如何在 FastReport .NET 中构建和安装 Postgres 插件

FastReport .NET 是一款全功能的Windows Forms、ASP.NET和MVC报表分析解决方案。 功能非常丰富&#xff0c;功能广泛。今天我们将介绍如何使用报表设计器的 FastReport 插件连接数据库。 FastReport .NET 是适用于.NET Core 3&#xff0c;ASP.NET&#xff0c;MVC和Windows窗体…

LlamaIndex 介绍

LlamaIndex 是什么&#xff1f; 从字面上理解&#xff0c;是 Llama Index&#xff0c;Llama 是大语言模型&#xff0c;Index 是索引&#xff0c;Index for Llama 就是为大语言模型做索引&#xff0c;那么大语言模型为什么需要索引&#xff0c;索引的作用是什么&#xff1f; …

CAS-ViT实战:使用CAS-ViT实现图像分类任务(一)

摘要 在视觉转换器&#xff08;Vision Transformers, ViTs&#xff09;领域&#xff0c;随着技术的不断发展&#xff0c;研究者们不断探索如何在保持高效性能的同时&#xff0c;降低模型的计算复杂度&#xff0c;以满足资源受限场景&#xff08;如移动设备&#xff09;的需求。…

住宅代理助力网页抓取,DaaS实现数据驱动的业务优化

什么是DaaS&#xff1f;有什么作用&#xff1f; DaaS的工作原理是什么&#xff1f;哪些行业需要&#xff1f; 如何应用DaaS&#xff1f; 网页抓取如何助力优化DaaS&#xff1f; 总结 在数字化转型的浪潮中&#xff0c;数据已成为企业决策和业务优化的核心资源。数据即服务&…

特殊采购转包

在转包期间&#xff0c;公司从外部供应商处订购物料。与正常外部采购流程不同&#xff0c;公司将为供应商&#xff08;转包商&#xff09;提供部分或全部用于物料生产的部件。 该流程拥有以下特征&#xff1a; 通过转包订单订购成品&#xff0c;该转包订单还包含有关要为转包商…

培训第三十二天(学习playbook-roles,脚本创建数据库和表,mycat读写分离)

上午 1、roles&#xff08;角色&#xff09;介绍 roles(⻆⾊): 就是通过分别将variables, tasks及handlers等放置于单独 的⽬录中,并可以便捷地调⽤它们的⼀种机制。 假设我们要写⼀个playbook来安装管理lamp环境&#xff0c;那么这个 playbook就会写很⻓。所以我们希望把这…

入门STM32—外部中断

外部中断的存在使得微控制器能够及时响应外部事件&#xff0c;避免频繁的轮询操作&#xff0c;从而提高系统的实时性、效率和低功耗性能。 1.什么是外部中断&#xff1f; 外部中断是指微控制器接收到外部引脚的信号变化时触发的中断。STM32F103系列微控制器支持多个外部中断线…