LeetCode刷题--- Dijkstra 求最短路径

news2024/10/6 22:31:01

首先是图的表示,邻接矩阵和邻接表。实现看代码

  • 邻接矩阵:二维数组,
    • matrix[a][b] 表示 从a可以指向b
    • 无向图而言, matrix[a][b]=matrix[b][a],比如可以定义matrix[a][b]=1表示ab是连接的,matrix[a][b]=0表示ab是不可连接的
    • 有向图:matrix[a][b]=x,表示从a到b的权是x,如果matrix[a][b]=无穷大,表示ab是不可连接的
  • 邻接表:
    • 外层是一个数组,数组长度表示图中有多少个节点,数组下标对应节点a
    • 每个数组中,存放一个链表,链表的每个节点也是数组
      • 链表长度代表从a可以直接指向多少个节点
      • 链表元素树一个数组,数组第一个元素代表被执向的b,第二个元素代表a到b的权

个人感觉,邻接矩阵适合无向图,邻接表适合有向图。

/**
 * 邻接矩阵
 *
 * @param n 初始化图中节点的个数
 * @param edges edges边,从edge[0]指向edge[1],路径长度为edge[2]
 * @return matrix
 */
public int[][] adjacentMatrix(int n, int[][] edges) {
    // 邻接矩阵就是一个二维数组,很好理解,对应坐标的值是路径长度
    int[][] matrix = new int[n][n];

    for (int[] edge : edges) {
        int start = edge[0];
        int end = edge[1];
        int length = edge[2];
        matrix[start][end] = length;
    }
    return matrix;
}

public List<int[]>[] adjacentList(int n, int[][] edges) {
    // 邻接列表,最外层是个数组,数组元素是一个列表
    // 列表中存储的数据,又是一个数组
    // 最外层数组,坐标代表edge[0]
    // 数组元素是个列表,这个列表存储的东西是 edge[1],edge[2]
    // 每个链表有多少元素,就说明这个点指向多少个别的点
    List<int[]>[] list = new List[n];
    for (int i = 0; i < n; i++) {
        list[i] = new ArrayList<>();
    }

    for (int[] edge : edges) {
        int start = edge[0];
        int end = edge[1];
        int length = edge[2];
        list[start].add(new int[] {end, length});
    }
    return list;
}

 2642. 设计可以求最短路径的图类

比如我们求从0 到其他点的最短距离,定义一个数组,第0行分别是每个节点,第一行是0到其他节点的距离,初始化为正无穷大,第三行是表示是否已经是最小距离。

0123
0
TFFF

 首先遍历0能够直接到达的顶点,修改如下,此时0到1的距离是最短的,可以标记为T

0123
025
TTFF

然后看从2出发,能够直接到达的距离

因为从1到2的距离是2+1,小于当前的5,因此可以刷新下表,此时得到了0到2最短距离3

0123
023
TTTF

思路就是上面的思路,不断的获取距离,然后和当前的距离比较,如果比他小,就更新进去。

public class Graph {

    List<int[]>[] graph;

    public Graph(int n, int[][] edges) {
        graph = adjacentList(n, edges);
    }

    public List<int[]>[] adjacentList(int n, int[][] edges) {
        List<int[]>[] list = new List[n];
        for (int i = 0; i < n; i++) {
            list[i] = new ArrayList<>();
        }

        for (int[] edge : edges) {
            int start = edge[0];
            int end = edge[1];
            int length = edge[2];
            list[start].add(new int[] {end, length});
        }
        return list;
    }

    // 向边集中添加一条边,本题的数据保证添加这条边之前对应的两个节点之间没有有向边
    // 这说明添加不会产生新的节点。即邻接矩阵外层的数组长度不会改变,只会改变数组元素的链表
    public void addEdge(int[] edge) {
        int start = edge[0];
        int end = edge[1];
        int length = edge[2];
        graph[start].add(new int[] {end, length});
    }

    public int shortestPath(int node1, int node2) {
        // 如果是同一个端点,说明路径为0,直接返回即可
        if (node1 == node2) {
            return 0;
        }

        // 定义一个距离数组,用于标识从当前node1出发,到所有点的最短路径,初始化值为Integer.MAX_VALUE,表示无穷大
        int[] distance = new int[graph.length];
        Arrays.fill(distance, Integer.MAX_VALUE);
        // node1到自身的距离为0;
        distance[node1] = 0;

        // 参考BFS,定义一个队列
        Queue<int[]> queue = new LinkedList<>();
        // 把node1变成节点传入队列中,队列存一个长度2的数组,分别表示到这个节点,距离
        queue.offer(new int[] {node1, 0});
        while (!queue.isEmpty()) {
            int[] poll = queue.poll();
            int cur = poll[0];
            int cost = poll[1];

            // if (cur == node2) {
            //     return cost;
            // }

            // 从邻接列表中取出当前节点可以指向的节点list,遍历这个list
            List<int[]> list = graph[cur];
            for (int[] arr : list) {
                int next = arr[0];
                int ncost = arr[1];
                // 如果路径和比当前小,就更新进去
                if (distance[next] > cost + ncost) {
                    distance[next] = cost + ncost;
                    queue.offer(new int[] {next, cost + ncost});
                }
            }
        }

        return distance[node2] == Integer.MAX_VALUE ? -1 : distance[node2];
    }
}

// 优化,如果我们定义一个优先级队列,这样每次BFS的时候,都会先遍历路径最小的节点
// 这样的话,就可以在while循环里面进行判断,如果等于目标节点,就可以直接返回了
Queue<int[]> queue = new PriorityQueue<>((a, b) -> a[1] - b[1]);

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

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

相关文章

Docker进阶:Docker Swarm —弹性伸缩调整服务的副本数量

Docker进阶&#xff1a;Docker Swarm —弹性伸缩调整服务的副本数量 1、 创建一个Nginx服务&#xff08;Manager节点&#xff09;2、查看服务状态&#xff08;Manager节点&#xff09;3、测试访问&#xff08;Worker节点&#xff09;4、查看服务日志&#xff08;Manager节点&am…

有效三角形的个数【双指针】

1.优化版暴力求解 如果能构成三⻆形&#xff0c;需要满⾜任意两边之和要⼤于第三边。实际上只需让较⼩的两条边之和⼤于第三边即可。将原数组排序&#xff0c;从⼩到⼤枚举三元组&#xff0c;这样三层 for 循环枚举出的三元组只需判断较⼩的两条边之和是否⼤于第三边。 class…

2024/3/24周报

文章目录 摘要Abstract文献阅读题目引言创新点数据处理研究区域和数据缺失值处理水质相关分析 方法和模型LSTMAttention机制AT-LSTM模型 实验结果 深度学习transformer代码实现1 模型输入1.1 Embedding层1.2 位置编码 2 Encoder2.1 编码器2.2 编码器层2.3注意力机制2.4多头注意…

Sora那么牛,他的模型的成本会有多少呢?

Sora的训练需要大量的计算资源&#xff0c;估计需要4211-10528个 Nvidia H100 GPUs运行一个月。推理成本&#xff1a;一个Nvidia H100 GPU大约每小时能生成5分钟的视频。初期的Sora成本将非常高&#xff0c;肯定是不适合普通人来使用&#xff0c;所以目前OpenAI都是先找一些艺术…

AttributeError: ‘ImageDraw‘ object has no attribute ‘textsize‘

用python绘制词云图时&#xff0c;出现报错AttributeError: ImageDraw object has no attribute textsize&#xff0c;应当如何解决&#xff1f; - CSDN文库

TikTok养号怎么做?打破0播放的前提是做好这些

TikTok养号的重要性不必多少&#xff0c;不仅可以在创号初期保障账号安全&#xff0c;后期的账号流量也需要以前期养好账号为前提。下面就给大家分享如何养号的真实操作攻略&#xff01; 一、为什么要养号 &#xff08;1&#xff09;提高系统推荐精准度 系统不了解新账户人设…

基于单片机病房温度监测与呼叫系统设计

**单片机设计介绍&#xff0c;基于单片机病房温度监测与呼叫系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机病房温度监测与呼叫系统设计概要主要涵盖了通过单片机技术实现病房温度的实时监测以及病人呼叫功能…

如何应对Android面试官->进程通信如何注册与获取服务

前言 大家好&#xff0c;我是老A&#xff1b; 这个章节继续上一章节继续讲解&#xff0c;主要讲解下 java 层服务的注册与获取、线程池&#xff1b;我们基于 AMS 来看下 java 层是如何获取的&#xff1b; SystemServer SystemServer 的启动也是 main 函数&#xff0c;我们进入…

三、阅读器开发--4、阅读器目录、全文搜索功能开发

1、阅读器目录 1.1、实现目录 先实现目录的布局 定义一个蒙版&#xff0c;充满整个屏幕浮在阅读器上方&#xff0c;左侧为目录右侧为背景&#xff0c;目录下方包含一个tab&#xff0c;点击后会切换不同的内容&#xff0c;这里tab是目录、书签&#xff0c;这里可以通过如下的…

(原型与原型链)前端八股文修炼Day5

一 原型链的理解 原型链定义&#xff1a; 原型链是 JavaScript 中实现对象继承的关键机制之一&#xff0c;它是一种对象之间的关系&#xff0c;通过这种关系&#xff0c;一个对象可以继承另一个对象的属性和方法。 原型链的组成&#xff1a; 每个对象都有一个指向另一个对象的…

【node】express使用(三)

1、express.static快速托管静态资源 express:快速、开放、极简的Web开发框架。(npm第三方包&#xff0c;提供快速创建web服务器便捷方法) Express中文官网 (1) express快速创建web网站服务器以及api接口服务器 // 1、导入express const express require(express) // 2、创…

ITES | 深圳工业展正运动重磅产品即将亮相

■展会名称&#xff1a; 第二十五届深圳国际工业制造技术及设备展览会&#xff08;以下简称“深圳工业展”&#xff09; ■展会日期 2024年3月28日-31日 ■展馆地点 中国深圳国际会展中心(宝安) ■展位号 9号馆F04 2024年深圳工业展(ITES)将于3月28日至31日在深圳宝安国…

Android Studio详细安装教程及入门测试

Android Studio 是 Android 开发人员必不可少的工具。 它可以帮助开发者快速、高效地开发高质量的 Android 应用。 这里写目录标题 一、Android Studio1.1 Android Studio主要功能1.2 Android应用 二、Android Studio下载三、Android Studio安装四、SDK工具包下载五、新建测试…

20240320-1-梯度下降

梯度下降法面试题 1. 机器学习中为什么需要梯度下降 梯度下降的作用&#xff1a; 梯度下降是迭代法的一种&#xff0c;可以用于求解最小二乘问题。在求解损失函数的最小值时&#xff0c;可以通过梯度下降法来一步步的迭代求解&#xff0c;得到最小化的损失函数和模型参数值。…

阶乘的最高位

阶乘的最高位 题目描述 输入一个正整数n。输出n!的最高位上的数字。 输入 输入一个正整数n&#xff08;n不超过1000&#xff09;。 输出 输出n!的最高位上的数字。 样例输入 1000样例输出 4解 这道题要是求阶乘的后三位或者后几位&#xff0c;大家肯定都会。 求最高…

web服务应用术语

一、HTTP 协议详解 TCP 协议与 HTTP 协议 TCP 协议主要用于数据传输控制&#xff0c;而 HTTP 协议主要用于应用层面的数据交互。 HTTP 属于应用层协议&#xff0c;是建立在 TCP 协议基础之上的&#xff0c;HTTP 协议以客户端请求和服务器端响应为标准&#xff0c;浏览器通常称…

JavaSE+JDBC进行控制台输出的客户管理系统! (实训/课堂实践推荐)

本人博客&#xff1a;玖玖的个人博客 (zhangxi.online)&#xff0c;欢迎大家来踩 该文章原地址&#xff1a; JavaSEJDBC进行控制台输出的客户管理系统! (实训/课堂实践推荐&#xff09; (zhangxi.online) 本人诚挚的特别感谢&#xff1a;尚硅谷/黑马程序员提供的学习案例 项…

玩转云计算:教你在Akamai Linode上构建IT架构–定义项目

时至今日&#xff0c;选择以云计算方式来运维业务&#xff0c;已经成为大部分情况下的最优选。那么如果要从零开始开发一个新应用&#xff0c;并依托云平台来设计、开发、部害和远维&#xff0c;具体该从何处下手&#xff1f;这一系列文章将介绍如何基于Akamai Linode平台实现这…

通过Appium和Xcode Accessibility Inspector获取iOS应用元素定位的方法

在 iOS 移动应用程序上使用选择器查找元素定位是我们在移动端 UI 自动化测试的先决条件。 但是&#xff0c;由于应用程序内容在原生 iOS 应用程序中的呈现方式&#xff0c;我们可以用来定位应用程序元素的选择器与 Web 浏览器元素有很大不同。 在本文中&#xff0c;我们将了解 …

将markdown文档中的图床外链图片下载到本地文件夹

markdown图床外链图片下载到本地代码 前言 因为文章发到先知或者攻防社区需要本地图片&#xff0c;而我的图片从来都是上传到图床&#xff0c;所以编写了一个脚本实现了把markdown文章中所有含有外链图床的图片转储到本地的文件夹。 然后发布文章时再手动一个个上传图片。 详细…