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

单源最短路径问题是指在加权图中,找到从单个源点到其他所有点的最短路径的问题。这是图论和网络优化中的一个经典问题,具有广泛的应用,如网络路由、交通规划、社交网络分析等。解决单源最短路径问题的算法有很多,其中最著名的包括迪杰斯特拉算法(Dijkstra’s Algorithm)和贝尔曼-福特算法(Bellman-Ford Algorithm)。

迪杰斯特拉算法(Dijkstra’s Algorithm)

迪杰斯特拉算法是一种贪心算法,适用于没有负权重边的图。它通过维护一个优先队列来选择距离源点最近的未访问顶点,并更新其相邻顶点的距离。

算法步骤

  1. 初始化所有顶点的距离为无穷大,将源点的距离设为0。
  2. 将所有顶点加入优先队列。
  3. 从优先队列中取出距离最小的顶点。
  4. 更新该顶点的所有未访问邻居的距离。
  5. 将更新后的邻居顶点加入优先队列。
  6. 重复步骤3-5,直到所有顶点都被访问。

贝尔曼-福特算法(Bellman-Ford Algorithm)

贝尔曼-福特算法适用于包含负权重边的图,但它比迪杰斯特拉算法慢。它的核心思想是通过多次迭代,逐步放松所有边,直到找到最短路径或者检测到负权重循环。

算法步骤

  1. 初始化所有顶点的距离为无穷大,将源点的距离设为0。
  2. 对图中的所有边进行V-1次迭代(V是顶点的数量),每次迭代尝试更新顶点的距离。
  3. 在每次迭代中,对于每条边(u, v),如果dist[u] + weight(u, v) < dist[v],则更新dist[v]。
  4. 检测是否存在负权重循环。

示例代码 - 迪杰斯特拉算法(Java):

import java.util.*;public class DijkstraAlgorithm {private final Map<Integer, Map<Integer, Integer>> graph;private final PriorityQueue<Vertex> minHeap;private final int[] distance;public DijkstraAlgorithm(Map<Integer, Map<Integer, Integer>> graph) {this.graph = graph;this.minHeap = new PriorityQueue<>();this.distance = new int[graph.size()];}public void findShortestPath(int source) {Arrays.fill(distance, Integer.MAX_VALUE);distance[source] = 0;minHeap.offer(new Vertex(source, 0));while (!minHeap.isEmpty()) {Vertex current = minHeap.poll();if (current.distance == distance[current.vertex]) {for (Map.Entry<Integer, Integer> neighbor : graph.get(current.vertex)) {int newDistance = current.distance + neighbor.getValue();if (newDistance < distance[neighbor.getKey()]) {distance[neighbor.getKey()] = newDistance;minHeap.offer(new Vertex(neighbor.getKey(), newDistance));}}}}}public static void main(String[] args) {Map<Integer, Map<Integer, Integer>> graph = new HashMap<>();graph.put(1, Map.of(2, 7, 3, 9, 6, 14));graph.put(2, Map.of(1, 7, 3, 10, 5, 8));graph.put(3, Map.of(1, 9, 2, 10, 4, 15, 6, 4));// ... 添加更多顶点和边DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(graph);dijkstra.findShortestPath(1);// 输出从顶点1到其他顶点的最短路径}private static class Vertex implements Comparable<Vertex> {int vertex;int distance;public Vertex(int vertex, int distance) {this.vertex = vertex;this.distance = distance;}@Overridepublic int compareTo(Vertex other) {return Integer.compare(this.distance, other.distance);}}
}

在面试中,了解并能够实现单源最短路径算法是非常重要的。通过这些问题和解决方案,面试官可以评估应聘者的算法理解和编程能力。希望这些信息能够帮助你更好地准备面试!单源最短路径问题是算法面试中的一个重要话题,尤其是在大厂的面试中。以下是三道可能出现在大厂面试中的与单源最短路径相关的编程题目,以及相应的Java源码实现。

题目 1:无权重的图的单源最短路径

描述
给定一个无权重的图,找到从单个源点到所有其他顶点的最短路径。

示例

输入: 图的邻接表表示,源点为 1
输出: [0, 1, 2, 3]

Java 源码(使用广度优先搜索):

import java.util.*;public class UnweightedShortestPath {public List<Integer> shortestPathUnweighted(int[][] graph, int src) {int n = graph.length;List<Integer> distances = new ArrayList<>();for (int i = 0; i < n; i++) {distances.add(Integer.MAX_VALUE);}distances.set(src - 1, 0);Queue<Integer> queue = new LinkedList<>();queue.offer(src);while (!queue.isEmpty()) {int current = queue.poll();for (int neighbor : graph[current - 1]) {if (distances.set(neighbor - 1, Math.min(distances.get(neighbor - 1), distances.get(current - 1) + 1))) {queue.offer(neighbor);}}}return distances;}public static void main(String[] args) {UnweightedShortestPath solution = new UnweightedShortestPath();int[][] graph = {{2, 3},{1, 3},{1, 4},{2, 4}};int src = 1;List<Integer> result = solution.shortestPathUnweighted(graph, src);System.out.println("Shortest paths from " + src + ": " + result);}
}

题目 2:有权重的图的单源最短路径

描述
给定一个有权重的图,找到从单个源点到所有其他顶点的最短路径。

示例

输入: 图的邻接表表示,源点为 1,边的权重为数组
输出: [0, 6, 8, 11]

Java 源码(使用迪杰斯特拉算法):

import java.util.*;public class WeightedShortestPath {public List<Integer> shortestPathWeighted(int[][] graph, int src) {int n = graph.length;List<Integer> distances = new ArrayList<>();for (int i = 0; i < n; i++) {distances.add(Integer.MAX_VALUE);}distances.set(src - 1, 0);PriorityQueue<Vertex> minHeap = new PriorityQueue<>();for (int i = 0; i < n; i++) {minHeap.offer(new Vertex(i + 1, distances.get(i)));}while (!minHeap.isEmpty()) {Vertex current = minHeap.poll();for (int[] edge : graph[current.vertex - 1]) {int neighbor = edge[0], weight = edge[1];if (distances.get(current.vertex - 1) + weight < distances.get(neighbor - 1)) {distances.set(neighbor - 1, distances.get(current.vertex - 1) + weight);minHeap.offer(new Vertex(neighbor, distances.get(neighbor - 1)));}}}return distances;}static class Vertex implements Comparable<Vertex> {int vertex;int distance;Vertex(int vertex, int distance) {this.vertex = vertex;this.distance = distance;}@Overridepublic int compareTo(Vertex other) {return Integer.compare(this.distance, other.distance);}}public static void main(String[] args) {WeightedShortestPath solution = new WeightedShortestPath();int[][] graph = {{2, 7}, {3, 9}, {4, 10},{1, 6}, {3, 15}, {4, 6},{1, 8}, {2, 11}, {4, 7}};int src = 1;List<Integer> result = solution.shortestPathWeighted(graph, src);System.out.println("Shortest paths from " + src + ": " + result);}
}

题目 3:存在负权重边的图的单源最短路径

描述
给定一个可能包含负权重边的图,找到从单个源点到所有其他顶点的最短路径。如果存在负权重循环,则报告错误。

示例

输入: 图的邻接表表示,源点为 1,边的权重为数组
输出: [0, 5, -3, 9]

Java 源码(使用贝尔曼-福特算法):

import java.util.*;public class NegativeWeightShortestPath {public List<Integer> shortestPathNegativeWeight(int[][] graph, int src) {int n = graph.length;int[] distances = new int[n];Arrays.fill(distances, Integer.MAX_VALUE);distances[src - 1] = 0;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < graph.length; j++) {for (int[] edge : graph[j]) {int neighbor = edge[0], weight = edge[1];if (distances[j] + weight < distances[neighbor - 1]) {distances[neighbor - 1] = distances[j] + weight;}}}}for (int i = 0; i < graph.length; i++) {for (int[] edge : graph[i]) {int neighbor = edge[0], weight = edge[1];if (distances[i] + weight < distances[neighbor - 1]) {throw new IllegalArgumentException("Graph contains a negative-weight cycle");}}}return Arrays.asList(distances);}public static void main(String[] args) {NegativeWeightShortestPath solution = new NegativeWeightShortestPath();int[][] graph = {{1, -1}, {2, 4},{1, 3}, {3, 2}, {3, -3},{2, 2}, {4, 3}};int src = 1;try {List<Integer> result = solution.shortestPathNegativeWeight(graph, src);System.out.println("Shortest paths from " + src + ": " + result);} catch (IllegalArgumentException e) {System.out.println(e.getMessage());}}
}

这些题目和源码展示了单源最短路径问题的不同变体以及如何在实际编程中解决它们。在面试中,能够根据问题的特点选择合适的算法并实现其解决方案是非常重要的。希望这些示例能够帮助你更好地准备面试!

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

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

相关文章

PHP一句话木马

一句话木马 PHP 的一句话木马是一种用于 Web 应用程序漏洞利用的代码片段。它通常是一小段 PHP 代码&#xff0c;能够在目标服务器上执行任意命令。一句话木马的工作原理是利用 Web 应用程序中的安全漏洞&#xff0c;将恶意代码注入到服务器端的 PHP 脚本中。一旦执行&#xf…

Java 分页查询

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Docker Container (容器) 常见命令

Docker 容器的生命周期 什么是容器&#xff1f; 通俗地讲&#xff0c;容器是镜像的运行实体。镜像是静态的只读文件&#xff0c;而容器带有运行时需要的可写文件层&#xff0c;并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容 器有初建、运行、停止、暂停和删除…

OpenXR API概览与核心组件解析

在虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;领域&#xff0c;OpenXR API提供了一个重要的开放标准&#xff0c;使得开发者能够跨多种硬件和软件平台创建兼容的应用。本文将详细解释OpenXR中的核心组件和数据结构&#xff0c;并探讨它们如何共同…

智能商品计划系统如何提升鞋服零售品牌的竞争力

国内鞋服零售企业经过多年的发展&#xff0c;已经形成了众多知名品牌&#xff0c;然而近年来一些企业频频受到库存问题的困扰&#xff0c;这一问题不仅影响了品牌商自身&#xff0c;也给长期合作的经销商带来了困扰。订货会制度在初期曾经有效地解决了盲目生产的问题&#xff0…

蓝桥杯刷题-计算系数

本文自用&#xff0c;用作记录。 211. 计算系数 - AcWing题库 #include <bits/stdc.h>using namespace std;int a, b, k ,n ,m; const int mod 10007; int qmi(int a, int k) {a % mod;int res 1;while (k){if (k & 1) res res * a % mod;a a * a % mod;k >…

机器学习方法在测井解释上的应用-以岩性分类为例

机器学习在测井解释上的应用越来越广泛&#xff0c;主要用于提高油气勘探和开发的效率和精度。通过使用机器学习算法&#xff0c;可以从测井数据中自动识别地质特征&#xff0c;预测岩石物理性质&#xff0c;以及优化油气储层的评估和管理。 以下是机器学习在测井解释中的一些…

OpenHarmony南向开发实例:【游戏手柄】

介绍 基于TS扩展的声明式开发范式编程语言&#xff0c;以及OpenHarmony的分布式能力实现的一个手柄游戏。 完成本篇Codelab需要两台开发板&#xff0c;一台开发板作为游戏端&#xff0c;一台开发板作为手柄端&#xff0c;实现如下功能&#xff1a; 游戏端呈现飞机移动、发射…

Windows 安装 Node.js 开发环境

一、简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;主要功能是编写像 web 服务器一样的网络应用。它使用事件驱动、非阻塞式 I/O 模型&#xff0c;可以优化应用程序的传输量和规模&#xff0c;非常适合在分布式设备上运行数据密集型的实时应用。 …

【C++】适配器· 优先级队列 仿函数 反向迭代器

目录 适配器&#xff1a;适配器的应用&#xff1a;1. 优先级队列&#xff1a;仿函数&#xff1a;更深入的了解仿函数&#xff1a;一个关于不容易被注意的知识点&#xff1a; 2. 反向迭代器&#xff1a;&#xff08;list为例&#xff09; 适配器&#xff1a; 我们先来谈来一下容…

【网络编程】如何创建一个自己的并发服务器?

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的网络编程系列之如何创建一个自己的并发服务器&#xff0c;在这篇文章中&#xff0c;你将会学习到在Linux内核中如何创建一个自己的并发服务器&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘UML图来帮助大家…

素描石膏像:写实与抽象的美学对话

正文&#xff1a; 素描&#xff0c;作为绘画艺术的基础&#xff0c;承载着艺术家对世界的独特理解和表达。在素描石膏像的创作中&#xff0c;写实与抽象两种风格的碰撞&#xff0c;不仅展现了艺术家的技巧&#xff0c;更是一场美学的对话。 一、写实风格&#xff1a;细节的捕…

基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于HMM隐马尔可夫模型的金融数据预测算法.程序实现HMM模型的训练&#xff0c;使用训练后的模型进行预测。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运…

CentOS 7 文件权限管理详解

CentOS 7 文件权限管理详解 在 CentOS 7 系统中,文件权限管理是一项至关重要的任务,它确保了系统安全、数据完整性和用户隐私。本文将详细介绍 CentOS 7 中的文件权限管理,包括相关文件和命令的使用。 一、文件权限基础 在 Linux 系统中,每个文件和目录都有与之关联的权…

简单工厂模式抽象工厂模式

一.简单工厂模式 1.什么是工厂模式 工厂模式的核心就是把对象的生产过程交给工厂来完成&#xff0c;当外部需要一个对象时&#xff0c;由工厂提供接口来获取对象&#xff0c;这样一来即使生产对象的过程变了&#xff0c;仍然不影响外部对对象的获取和使用。 2.举个栗子 定义…

云计算笔记

RAID的组合方式 RAID0&#xff1a;多个硬盘同时工作&#xff0c;可提供性能&#xff0c;无冗余机制 RAID1&#xff1a;数据保存多份&#xff0c;提供冗余机制&#xff0c;性能受到影响 RAID3&#xff1a;存在数据盘和单独校验盘&#xff0c;数据写入 至数据盘后需要运算且将…

吃透2000-2024年600道真题和解析,科学高效通过2025年AMC8竞赛

为帮助孩子科学、有效备考AMC8竞赛&#xff0c;我整理了2000-2004年的全部AMC8真题&#xff08;完整版共600道&#xff0c;且修正了官方发布的原试卷中的少量bug&#xff09;&#xff0c;并且独家制作成多种在线练习&#xff0c;利用碎片化时间&#xff0c;8个多月的时间足以通…

Django中的实时通信:WebSockets与异步视图的结合【第167篇—实时通信】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在现代Web应用程序中&#xff0c;实时通信已经成为了必不可少的功能之一。无论是在线聊天、…

爆肝3k字!掌握Spring与Redis的高效交互:从Jedis到Spring Data Redis

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

甲辰年三月初九有感

甲辰年三月初九有感 雨多汇成洪&#xff0c;梅酸长几成&#xff1f; ​久旱微巨调&#xff0c;点积多少恒。 ​时光沙漏里&#xff0c;情境入己梦。 望山山外山&#xff0c;​登顶人为峰。