Java最短路径算法知识点(含面试大厂题和源码)

最短路径算法是计算机科学和图论中的核心问题之一,它旨在找到从一个顶点到另一个顶点或在所有顶点之间的最短路径。这个问题在多种实际应用中都非常重要,如网络路由、交通规划、社交网络分析等。以下是一些与最短路径算法相关的知识点:

  1. Dijkstra算法:

    • 由荷兰计算机科学家艾兹赫尔·戴克斯特拉(Edsger W. Dijkstra)在1956年提出。
    • 适用于带权重的有向图和无向图,且所有权重必须为非负值。
    • 算法使用贪心策略,通过不断地扩展已知最短路径集合来找到从源点到其他所有点的最短路径。
    • 时间复杂度取决于所使用的数据结构,使用优先队列时可以达到O(|V|^2 + |E|log|V|),其中|V|是顶点数,|E|是边数。
  2. Bellman-Ford算法:

    • 可以处理带有负权重边的图,但不允许存在负权重循环。
    • 通过对所有边进行|V|-1次松弛操作来逐步找到最短路径。
    • 时间复杂度为O(|V||E|),在稀疏图中效率较低。
  3. Floyd-Warshall算法:

    • 一种动态规划算法,用于计算所有顶点对之间的最短路径。
    • 可以处理带有正权重或负权重(但不包含负权重循环)的图。
    • 时间复杂度为O(|V|^3),适用于稠密图。
  4. A*搜索算法:

    • 一种启发式搜索算法,用于在图中找到从起点到目标点的最短路径。
    • 通过评估函数(如曼哈顿距离或欧几里得距离)来估计从当前顶点到目标点的最短距离,并优先搜索估计距离最小的路径。
    • 适用于有向图和无向图,且通常用于路径查找问题,如地图导航。
  5. Yen’s K最短路径算法:

    • 用于在加权图中找到从单一源点到目标点的前K条最短路径。
    • 基于Dijkstra算法的扩展,通过维护一个优先队列来存储当前找到的K条最短路径。
    • 时间复杂度取决于K的大小,对于每条路径的搜索时间复杂度为O(|E|log|V|)。
  6. 数据结构:

    • 在实现最短路径算法时,选择合适的数据结构非常重要,如优先队列、堆、图的邻接矩阵或邻接表等。
    • 正确的数据结构可以显著提高算法的效率。
  7. 优化技巧:

    • 减少不必要的计算和比较次数,例如使用启发式信息来指导搜索方向,或者在Dijkstra算法中使用双向搜索。
    • 利用问题的特定性质,如对称性或稀疏性,来优化算法。
  8. 实际应用:

    • 了解最短路径问题在不同领域的应用可以帮助更好地理解算法的实际意义。
    • 例如,在网络路由中,最短路径算法可以帮助确定数据包的最佳传输路径;在交通规划中,可以用于找到从一个地方到另一个地方的最快路线。

通过深入理解上述知识点,你将能够更好地解决最短路径问题,并在面试中展示你的算法设计和分析能力。在准备面试时,建议通过实际编程练习来巩固这些概念,并准备好讨论不同算法的适用场景和限制。

题目 1:Dijkstra算法 - 找到从单个源点到图中所有其他顶点的最短路径

描述
给定一个加权图和一个源顶点,使用Dijkstra算法找到从该源顶点到图中所有其他顶点的最短路径。

要求

  • 图的边权重必须为非负值。
  • 返回一个包含每个顶点最短路径长度的数组。

Java代码示例

import java.util.*;class Graph {private int V; // 顶点的数量private List<List<Edge>> adj; // 邻接表class Edge {int v;int weight;Edge(int v, int weight) {this.v = v;this.weight = weight;}}Graph(int V) {this.V = V;adj = new ArrayList<>();for (int i = 0; i < V; ++i)adj.add(new ArrayList<>());}void addEdge(int u, int v, int weight) {adj.get(u).add(new Edge(v, weight));}void dijkstra(int s) {boolean[] visited = new boolean[V];int[] shortestPath = new int[V];Arrays.fill(shortestPath, Integer.MAX_VALUE);PriorityQueue<Vertex> minHeap = new PriorityQueue<>();visited[s] = true;minHeap.offer(new Vertex(s, 0));while (!minHeap.isEmpty()) {Vertex current = minHeap.poll();int u = current.id;int dist = current.dist;if (dist <= shortestPath[u])continue;for (Edge e : adj.get(u)) {int v = e.v;int weight = e.weight;if (!visited[v] && dist + weight < shortestPath[v]) {shortestPath[v] = dist + weight;minHeap.offer(new Vertex(v, shortestPath[v]));}}}// 输出结果for (int i = 0; i < V; i++) {System.out.print("Vertex " + i + " shortest path from source: " + shortestPath[i] + "\n");}}
}class Vertex implements Comparable<Vertex> {int id;int dist;Vertex(int id, int dist) {this.id = id;this.dist = dist;}@Overridepublic int compareTo(Vertex other) {return Integer.compare(this.dist, other.dist);}
}public class DijkstraExample {public static void main(String[] args) {Graph g = new Graph(5);g.addEdge(0, 1, 10);g.addEdge(0, 2, 3);g.addEdge(1, 2, 1);g.addEdge(1, 3, 2);g.addEdge(2, 1, 4);g.addEdge(2, 3, 8);g.addEdge(2, 4, 2);g.addEdge(3, 4, 7);g.dijkstra(0);}
}

题目 2:Floyd-Warshall算法 - 找到图中所有顶点对的最短路径

描述
给定一个加权图,使用Floyd-Warshall算法找到所有顶点对之间的最短路径。

要求

  • 图中可能包含负权重的边,但不允许存在负权重循环。
  • 返回一个二维数组,其中每个元素表示两个顶点之间的最短路径长度。

Java代码示例

public class FloydWarshallExample {public static void main(String[] args) {int V = 5;int[][] graph = {{0, 5, float.POSITIVE_INFINITY, 10, float.POSITIVE_INFINITY},{float.POSITIVE_INFINITY, 0, 3, float.POSITIVE_INFINITY, 8},{float.POSITIVE_INFINITY, 7, 0, 2, float.POSITIVE_INFINITY},{10, float.POSITIVE_INFINITY, float.POSITIVE_INFINITY, 0, 1},{float.POSITIVE_INFINITY, 8, float.POSITIVE_INFINITY, 7, 0}};for (int k = 0; k < V; k++) {for (int i = 0; i < V; i++) {for (int j = 0; j < V; j++) {if (graph[i][k] + graph[k][j] < graph[i][j]) {graph[i][j] = graph[i][k] + graph[k][j];}}}}// 打印结果for (int i = 0; i < V; i++) {for (int j = 0; j < V; j++) {System.out.print(graph[i][j] + " ");}System.out.println();}}
}

题目 3:A*搜索算法 - 在图中找到从起点到目标点的最短路径

描述
给定一个图和一个启发式函数,使用A*搜索算法找到从起点到目标点的最短路径。

要求

  • 启发式函数应估计从当前顶点到目标点的最小成本。
  • 返回从起点到目标点的最短路径及其长度。

Java代码示例(简化版):

import java.util.PriorityQueue;
import java.util.Comparator;class Node {int x, y;int g, h;Node(int x, int y, int g, int h) {this.x = x;this.y = y;this.g = g;this.h = h;}@Overridepublic String toString() {return "(" + x + ", " + y + ")";}
}public class AStarExample {public static void main(String[] args) {// 假设的地图和启发式函数int[][] map = {{0, 1, 0, 0, 0},{1, 1, 1, 1, 0},{0, 0, 0, 1, 0},{0, 1, 1, 1, 1},{0, 0, 0, 0, 0}};int start = 0; // 起点位置int goal = 14; // 目标位置(地图上的位置索引)// 启发式函数(曼哈顿距离)int[] dx = {1, 0, -1, 0};int[] dy = {0, 1, 0, -1};int h(int x, int y) {int d = Math.abs(x / 4 - goal / 4) + Math.abs(y / 4 - goal % 4);return d;}// A* 算法实现PriorityQueue<Node> queue = new PriorityQueue<>(Comparator.comparingInt(a -> a.g + a.h));queue.offer(new Node(start / 4, start % 4, 0, h(start / 4, start % 4)));while (!queue.isEmpty()) {Node current = queue.poll();if (current.x * 4 + current.y == goal) {System.out.println("Found path: " + current);break;}// 探索邻居节点for (int i = 0; i < 4; i++) {int nx = current.x + dx[i];int ny = current.y + dy[i];if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && map[nx][ny] == 0) {int ng = current.g + 1;int nh = h(nx, ny);queue.offer(new Node(nx, ny, ng, nh));}}}}
}

请注意,上述代码示例是简化版的,实际面试中可能需要更详细的实现和解释。在准备面试时,你应该确保理解每个算法的原理,并能够根据面试官的要求编写完整的代码。此外,讨论算法的时间复杂度和空间复杂度,以及如何处理特殊情况(如负权重边或非常大的图)也是非常重要的。

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

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

相关文章

DHT11温湿度传感器使用视频教程分享

下载地址&#xff1a; 温湿度计(STCDHT11): https://url83.ctfile.com/d/45573183-60623983-9b7f6c?p7526 (访问密码: 7526)

Java常用类和基础API

文章目录 1. 字符串相关类之不可变字符序列&#xff1a;String1.1 String的特性1.2 String的内存结构1.2.1 概述1.2.2 练习类型1&#xff1a;拼接1.2.3 练习类型2&#xff1a;new1.2.4 练习类型3&#xff1a;intern() 1.3 String的常用API-11.3.1 构造器1.3.2 字符串对象的比较…

解决酷狗官网无法播放音乐问题

播放歌曲页面无法播放歌曲&#xff0c;有CORS错误&#xff0c;困扰我很久了。 谷歌浏览器优雅的关闭cors跨域_浏览器关闭跨域-CSDN博客 "C:\Program Files\CatsxpSoftware\Catsxp-Browser\Application\catsxp.exe" --disable-web-security --user-data-dirE:\catsxp…

【学习笔记】java项目—苍穹外卖day10

文章目录 苍穹外卖-day10课程内容1. Spring Task1.1 介绍1.2 cron表达式1.3 入门案例1.3.1 Spring Task使用步骤1.3.2 代码开发1.3.3 功能测试 2.订单状态定时处理2.1 需求分析2.2 代码开发2.3 功能测试 3. WebSocket3.1 介绍3.2 入门案例3.2.1 案例分析3.2.2 代码开发3.2.3 功…

JavaScript之applye、bind和call方法详解

Question Q1 apply()、bind()和call()方法的区别在哪&#xff1f; Q2 apply()和call()的应用场景 Q3 apply()、bind()和call()方法手写实现逻辑 来源 继承自Function.prototype&#xff0c;属于实例方法 console.log(Function.prototype.hasOwnProperty(call)) //trueconsole.l…

Fusion360修改嘉立创EDA专业版生成的3D外壳文件

需要第三方软件的原因 嘉立创EDA专业版生成电路板的3D外壳文件是比较快捷的&#xff0c;但如果侧面精密开孔或者添加其它非常规的元素还是有些局限。嘉立创EDA专业版可以把3D外壳文件导出&#xff0c;这就大大方便了第三方软件的修改。 本文是利用Fusion360修改3D外壳文件&…

Waifu2x:使用深度卷积神经网络的动漫风格艺术的图像超分辨率

Github网址&#xff1a;nagadomi/waifu2x&#xff1a;动漫风格艺术的图像超分辨率 (github.com) 该项目主要讲述的是如何利用预训练的深度学习模型来达到无损扩大收缩和去噪&#xff0c;对于一般训练图像的小伙伴应该很清晰图像经常要通过resize操作固定大小&#xff0c;然后c…

个人推荐Redis比较好的一种使用规范

随着对个人项目的不断开发、迭代和重构&#xff0c;博主在这个过程中总结出了一套使用redis的较好的规范。主要包含Redis的key命名规范和Redis代码规范。 主要内容 主要包含以下几个内容&#xff1a; 同一应用的key在最前面添加统一的前缀&#xff0c;如应用名&#xff1b; 案…

某华为hr擅自给我报名机

某华为hr擅自报名机考 上周&#xff0c;牛客网一位同学爆料&#xff1a; ❝ 今年一月份&#xff0c;华为一位 HR 通过某招聘网站联系到他&#xff0c;然后通过该 HR 加上了业务工程师的微信。随后&#xff0c;该工程师在「经过他本人同意」的情况下&#xff0c;在系统录入了他的…

CSGO比赛赛事大科普,Major并不是一个赛事!

关于CSGO比赛&#xff0c;有很多人都听过许多相关名词&#xff1a;Major、Minor、IEM、EPL、ESL ONE、Dreamhack、ESEA、Blast、EPICENTER等等&#xff0c;但大家有没有想过这些名词所代表的含义呢&#xff1f; Major、Minor严格意义上说&#xff0c;Major、Minor本身并不是赛事…

深入浅出 -- 系统架构之分布式架构

​​​​​​分布式架构&#xff1a; 根据业务功能对系统做拆分&#xff0c;每个业务功能模块作为独立项目开发&#xff0c;称为一个服务。 当垂直应用越来越多时&#xff0c;应用之间的交互不可避免&#xff0c;可将共用的基础服务或核心模块抽取出来作为独立服务&#xff0c…

接口练习题目

练习一 1、声明接口Eatable&#xff0c;包含抽象方法public abstract void eat(); 2、声明实现类中国人Chinese&#xff0c;重写抽象方法&#xff0c;打印用筷子吃饭 3、声明实现类美国人American&#xff0c;重写抽象方法&#xff0c;打印用刀叉吃饭 4、声明实现类印度人Indi…

GDPU 竞赛技能实践 天码行空6

&#x1f4d6; 敌兵布阵 C国的死对头A国这段时间正在进行军事演习&#xff0c;所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段&#xff0c;所以每个工…

使用PostgreSQL中的隐式转换解决,MybatisPlus插入数据库时的类型不一致的问题

使用PostgreSQL中的隐式转换解决,MybatisPlus插入数据库时的类型不一致的问题 问题描述 鄙人在使用 MybatisPlus插件开发一个SpringBoot项目时, 遇到数据库中employee表与Java实体对象中某个属性的类型不一致, 导致插入数据库失败. 具体问题截图如下: 具体原因在于, Java实体…

Java入门教程||Java 多线程编程

Java 多线程编程 Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每一部分都称作一个线程&#xff0c;并且每个线程定义了一个独立的执行路径。 多线程是多任务的一种特别的形式。多线程比多任务需要更小的开销。 这里定义和线程…

usbserial驱动流程解析_Part1_主要函数

本系列解析usbseiral ko的源码&#xff0c;记录主要函数&#xff0c;调用流程&#xff0c;USB一端和串口一端的注册流程&#xff0c;本节简介主要函数以及替换规则。 首先&#xff0c;usbserial是USB转串口驱动的一个基础模板&#xff0c;其中有许多默认函数&#xff0c;他们的…

书生·浦语训练营二期第二次课后作业

文章目录 基础作业使用 InternLM2-Chat-1.8B 模型生成 300 字的小故事 进阶作业熟悉 huggingface 下载功能完成 浦语灵笔2 的 图文创作 及 视觉问答 部署图文创作视觉问答 完成 Lagent 工具调用 数据分析 Demo 部署 作业详细操作步骤见第二次课笔记&#xff1a;https://blog.cs…

CSS层叠样式表学习(字体属性)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS字体属性的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 三、CSS字体属性 CSS Fonts(字体)属性用于定义字体系列、大小&#xff0c;粗细&#xff0c;和文字样式(如斜…

list的常用接口底层实现与介绍

目录 概念&#xff1a; list的基本结构&#xff1a; list的迭代器⭐❤&#xff1a; 自定义类型的完善&#xff1a; const的迭代器&#xff1a; insert erase&#xff1a; size empty push_back 、push_front 、pop_back、pop_front swap 、operator 析构函数…

什么是CSGO游戏搬砖及游戏搬砖注意事项?

CSGO市场是指《反恐精英&#xff1a;全球攻势》游戏内的物品交易市场。玩家可以在这个市场上买卖各类虚拟物品&#xff0c;包括武器皮肤、刀具、手套等。CSGO市场的价格是由供需关系、稀有度、流行度等多个因素影响的。 一般来说&#xff0c;稀有度较高或者比较受欢迎的物品价格…