Java的Prim算法知识点(含面试大厂题和源码)

Prim算法是一种用于求解加权无向图的最小生成树问题的贪心算法。最小生成树是指在一个加权无向图中,连接所有顶点的权值最小的树。Prim算法通过逐步增加新的边和顶点来构建最小生成树。以下是Prim算法的一些关键知识点:

1. 算法概述

Prim算法从图中的任意一个顶点开始,初始化一个优先队列(通常是最小堆),用于存储所有连接已选顶点和未选顶点的边。每次从优先队列中取出权值最小的边,并将其对应的顶点加入到最小生成树中。重复这个过程,直到所有顶点都被包含在最小生成树中。

2. 算法步骤

  1. 选择图中的任意一个顶点作为起始点,将其加入到最小生成树集合中。
  2. 将所有与当前最小生成树集合中的顶点相连的边加入到优先队列中。
  3. 从优先队列中取出权值最小的边(即堆顶元素),如果这条边连接的顶点不在最小生成树集合中,则将该顶点和边加入到最小生成树中,并将这条边的所有相邻边加入到优先队列中。
  4. 重复步骤3,直到所有顶点都被加入到最小生成树中。

3. 数据结构

Prim算法主要使用了优先队列(最小堆)这一数据结构来维护边的权值。优先队列能够在O(log n)的时间复杂度内取出权值最小的边,这是算法效率的关键。

4. 时间复杂度

Prim算法的时间复杂度取决于优先队列的实现。使用二叉堆作为优先队列时,算法的时间复杂度为O(E log V),其中E是边的数量,V是顶点的数量。如果使用斐波那契堆作为优先队列,时间复杂度可以进一步降低到O(E + V log V)。

5. 空间复杂度

Prim算法的空间复杂度主要取决于存储边和顶点的数据结构。通常,算法需要额外的空间来存储已选择的边和优先队列中的边,空间复杂度为O(E)。

6. 算法适用性

Prim算法适用于稠密图,即边的数量接近顶点数量的平方的图。在稀疏图中,Kruskal算法可能是一个更好的选择,因为它的时间复杂度与边的数量有关,而不与顶点的数量有关。

7. 算法优化

可以通过优化数据结构来提高Prim算法的效率。例如,使用斐波那契堆作为优先队列可以减少算法的时间复杂度。此外,如果图的边数不是很大,可以考虑使用动态规划或其他方法来优化算法。

8. 实现示例

以下是使用Java实现Prim算法的一个简单示例:

import java.util.*;public class PrimMST {private static class Edge implements Comparable<Edge> {int from, to, weight;public Edge(int from, int to, int weight) {this.from = from;this.to = to;this.weight = weight;}public int compareTo(Edge other) {return Integer.compare(this.weight, other.weight);}}public List<Edge> primMST(int[][] graph, int n) {boolean[] visited = new boolean[n];List<Edge> mst = new ArrayList<>();PriorityQueue<Edge> pq = new PriorityQueue<>();for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {pq.offer(new Edge(i, j, graph[i][j]));}}int totalWeight = 0;while (!pq.isEmpty()) {Edge currentEdge = pq.poll();if (!visited[currentEdge.from] && !visited[currentEdge.to]) {mst.add(currentEdge);totalWeight += currentEdge.weight;visited[currentEdge.from] = true;visited[currentEdge.to] = true;// 移除已经访问过的顶点的边for (Edge edge : pq) {if (edge.from == currentEdge.from || edge.to == currentEdge.to) {pq.remove(edge);}}}}return mst;}public static void main(String[] args) {PrimMST primMST = new PrimMST();int n = 4;int[][] graph = {{0, 1, 0, 0},{1, 0, 1, 1},{0, 1, 0, 1},{0, 1, 1, 0}};List<Edge> result = primMST.primMST(graph, n);System.out.println("Total weight of MST: " + result.stream().mapToInt(Edge::getWeight).sum());}
}

通过掌握这些知识点,你可以更好地理解和实现Prim算法,从而在面试中解决相关的图论问题。

题目 1:字符串中的第一个唯一字符

问题描述:给定一个字符串,找到字符串中第一个不重复的字符。

解决方案:使用哈希表记录每个字符出现的次数,然后遍历字符串,找到第一个计数为1的字符。

Java 源码

public class FirstUniqueChar {public char firstUniqChar(String s) {if (s == null || s.isEmpty()) {return '#';}int[] count = new int[256]; // 假设字符集大小为256for (int i = 0; i < s.length(); i++) {count[s.charAt(i)]++;}for (int i = 0; i < s.length(); i++) {if (count[s.charAt(i)] == 1) {return s.charAt(i);}}return '#';}
}

题目 2:有效的括号

问题描述:给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

解决方案:使用栈数据结构,遇到左括号就入栈,遇到右括号就出栈,如果栈为空或者最后栈中还有元素,则字符串无效。

Java 源码

import java.util.Stack;public class ValidParentheses {public boolean isValid(String s) {Stack<Character> stack = new Stack<>();for (char c : s.toCharArray()) {if (c == '(' || c == '{' || c == '[') {stack.push(c);} else {if (stack.isEmpty()) {return false;}char last = stack.pop();if ((c == ')' && last != '(') || (c == '}' && last != '{') || (c == ']' && last != '[')) {return false;}}}return stack.isEmpty();}
}

题目 3:合并两个有序数组

问题描述:给定两个有序整数数组 nums1nums2,在不使用额外空间的情况下,将 nums2 合并到 nums1 中。

解决方案:从两个数组的末尾开始比较元素大小,将较大的元素放到 nums1 的末尾,直到 nums2 被完全合并。

Java 源码

public class MergeSortedArray {public void merge(int[] nums1, int m, int[] nums2, int n) {int p1 = m - 1; // nums1 的最后一个元素的索引int p2 = n - 1; // nums2 的最后一个元素的索引int p = m + n - 1; // 合并后数组的最后一个元素的索引while (p1 >= 0 && p2 >= 0) {if (nums1[p1] > nums2[p2]) {nums1[p--] = nums1[p1--];} else {nums1[p--] = nums2[p2--];}}while (p2 >= 0) {nums1[p--] = nums2[p2--];}}
}

这些题目涵盖了哈希表、栈和数组操作等常见的数据结构和算法知识点,是面试中常见的问题类型。在准备面试时,理解和掌握这些问题的解决方法对于成功通过技术面试至关重要。

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

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

相关文章

备考ICA----Istio实验13---使用 Istio Ingress 暴露应用

备考ICA----Istio实验13—使用Istio Ingress TLS暴露应用 1. 环境部署 清理之前实验遗留,并重新部署httpbin服务进行测试 # 清理之前的环境 kubectl delete vs httpbin kubectl delete gw mygateway # 部署httpbin kubectl apply -f istio/samples/httpbin/httpbin.yaml 确认…

C#WPF将变量或自定义数据类绑定到控件实例

本文实例讲解C#WPF将变量或自定义数据类如何绑定到控件。 目录 一、将普通变量绑定到控件实例 方式一 仅使用XAML来创建数据绑定。

c++11 标准模板(STL)本地化库 - std::isgraph(std::locale) 检查字符是否被本地环境分类为图形字符

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 检查字符是否被本地环境分类为图形字符 std::isgraph(std::locale) templat…

vue3使用vuedraggable实现拖拽(有过渡)

1. 安装与使用 vue中vuedraggable安装&#xff1a; pnpm i -S vuedraggablenext或者 yarn add vuedraggablenext注意&#xff1a;vue2和vue3安装的是不同版本的vuedraggable&#xff0c;写法上也会有一些区别。 比如在vue3中使用拖拽&#xff0c;要以插槽的方式&#xff0c;…

【微服务】Sentinel(熔断降级,热点限流)

文章目录 1.熔断降级1.基本介绍1.线程堆积引出熔断降级2.示意图3.熔断&#xff0c;降级&#xff0c;限流三者之间的关系 2.熔断降级策略&#xff08;以分钟为基本单位&#xff09;1.慢调用比例2.异常比例3.异常数 3.熔断降级实例—慢调用比例1.需求分析2.com/sun/springcloud/c…

个人简历主页搭建系列-05:部署至 Github

前面只是本地成功部署网站&#xff0c;网站运行的时候我们可以通过 localhost: port 进行访问。不过其他人是无法访问我们本机部署的网站的。 接下来通过 Github Pages 服务把网站部署上去&#xff0c;这样大家都可以通过特定域名访问我的网站了&#xff01; 创建要部署的仓库…

CAS、AQS、ReentrantLock机制以原理

1、CAS 1.1 基本概念 CAS 是 compare and swap 的简写&#xff0c;即比较并交换。它是指一种操作机制&#xff0c;而不是某个具体的类或方法。在 Java 平台上对这种操作进行了包装。在 Unsafe 类中&#xff0c;调用代码如下 这里无法用Unsafe类看&#xff0c;我使用的是Atomi…

绿联 部署vocechat,搭建私人聊天服务器,用于小型团队和家庭环境

1、镜像 privoce/vocechat-server:latest 2、安装 2.1、基础设置 重启策略&#xff1a;容器退出时总是重启容器。 2.2、网络 桥接即可。 2.3、存储空间 装载路径&#xff1a;/home/vocechat-server/data不可变更&#xff0c;权限读写。 2.4、端口设置 容器端口3000不可变…

go实现哈夫曼编码

package main import ( "bytes" "fmt" ) // 定义节点类型 type Node struct { Weight int Left *Node Right *Node } // 构建哈夫曼树 func buildHuffmanTree(weights []int) *Node { var nodes []*Node for _, weig…

鸿蒙OS开发教学:【编程之重器-装饰器】

HarmonyOS 有19种装饰器 必须【2】 绘制一个页面&#xff0c;这两个肯定会用到 EntryComponent 可选【17】 StatePropLinkObjectLinkWatchStylesStoragePropStorageLinkProvideConsumeObservedBuilderBuilderParamLocalStoragePropLocalStorageLinkExtendConcurrent 如果…

Redis--缓存常用的 3 种读写策略

Cache Aside Pattern旁路缓存模式 Cache Aside Pattern 是平时使用较多的一个缓存读写模式&#xff0c;比较适合读请求比较多的场景。 Cache Aside Pattern 中服务端需要同时维系 db 和 cache&#xff0c;并且是以 db 的结果为准。 缓存读写步骤&#xff1a; 写&#xff1a…

python3将exe 转支持库错误 AssertionError: None does not smell like code

exe -> pyc包(*.exe_extracted) 安装反编译工具 exe反编译工具&#xff1a;pyinstxtractor.py下载&#xff1a;https://sourceforge.net/projects/pyinstallerextractor/ python pyinstxtractor.py hello.exe包反编译 懒的写&#xff01;&#xff01;&#xff01; 这有详…

如何使用Zabbix监控MySQL的MGR群集状态

MySQL的MGR&#xff08;MySQL Group Replication&#xff09;是MySQL官方提供的一种高可用性和高可靠性的集群解决方案。MGR通过使用基于组复制的方式&#xff0c;实现了多个MySQL实例之间的数据同步和故障转移&#xff0c;从而提供了自动故障恢复和负载均衡的功能。本文将介绍…

安装uim-ui插件不成功,成功解决

安装&#xff1a;这种安装&#xff0c;umi4 不支持&#xff0c;只有umi3才支持。而我发现官网现在默认使用的umi4。 yarn add umijs/preset-ui -D 解决&#xff1a;更改umi版本重新安装umi3 npm i ant-design/pro-cli3.1.0 -g #使用umi3 (指定umi3版本) pro create user-ce…

【YOLOv8 代码解读】数据增强代码梳理

1. LetterBox增强 当输入图片的尺寸和模型实际接收的尺寸可能不一致时&#xff0c;通常需要使用LetterBox增强技术。具体步骤是先将图片按比例缩放&#xff0c;将较长的边缩放到设定的尺寸以后&#xff0c;再将较短的边进行填充&#xff0c;最终短边的长度为stride的倍数即可。…

爬虫(Web Crawler)逆向技术探索

实战案例分析 为了更好地理解爬虫逆向的实际应用&#xff0c;我们以一个具体的案例进行分析。 案例背景 假设我们需要从某电商网站上获取商品价格信息&#xff0c;但该网站采取了反爬虫措施&#xff0c;包括动态Token和用户行为分析等。 分析与挑战 动态Token&#xff1a;…

海豚【货运系统源码】货运小程序【用户端+司机端app】源码物流系统搬家系统源码师傅接单

技术栈&#xff1a;前端uniapp后端vuethinkphp 主要功能&#xff1a; 不通车型配置不通价格参数 多城市定位服务 支持发货地 途径地 目的地智能费用计算 支持日期时间 预约下单 支持添加跟单人数选择 支持下单优惠券抵扣 支持司机收藏订单评价 支持订单状态消息通知 支…

Photoshoot 2(Java)

Photoshoot 2 题目描述 在一个似曾相识的场景中&#xff0c;Farmer John 正在将他的 N 头奶牛&#xff08;1≤N≤10^5&#xff09;排成一排&#xff08;为了方便将它们按 1⋯1⋯N 编号&#xff09;&#xff0c;以便拍照。 最初&#xff0c;奶牛从左到右按照 a1,a2,⋯,aN 的顺…

【C/C++】从零开始认识C++历程-启航篇

文章目录 &#x1f4dd;前言&#x1f320; 什么是C&#xff1f;&#x1f309;C的发展史 &#x1f320;C的重要性&#x1f309;语言的使用广泛度 &#x1f320;在工作领域&#x1f309; 岗位需求 &#x1f320;相关笔试题&#x1f309; 公司怎样面试C &#x1f6a9;总结 &#x…

用grafana+prometheus+cadvisor监控容器指标数据,并查询当前容器的网速网络用量

前言 整理技术&#xff0c;在这篇文章中&#xff0c;将会搭建grafanaprometheuscadvisor监控容器&#xff0c;并使用一个热门数据看板&#xff0c;再监控容器的性能指标 dashboard效果 这个是node-exporter采集到的数据&#xff0c;我没装node-exporter&#xff0c;而且这也…