Java并查集(含面试大厂题和源码)

并查集(Union-Find)是一种用于处理一些不交集合合并及集合间元素查找问题的数据结构。它提供了两个主要的操作:查找(Find)和合并(Union)。查找操作用于确定某个元素属于哪个集合,而合并操作用于将两个集合合并为一个集合。

并查集的基本操作:

  1. 查找(Find):确定某个元素属于哪个集合,通常通过路径压缩来优化,使得每次查找都能快速定位到集合的代表元素。
  2. 合并(Union):将两个元素所在的集合合并为一个集合,通常通过按秩合并(Union by Rank)来优化,以保持树的平衡,从而提高操作效率。

并查集的实现方式:

  • 数组:使用数组来表示集合的代表元素和集合的秩(树的高度)。
  • :使用树形结构来表示集合的层次关系,每个元素都有一个指向其父集合的指针。

并查集的Java实现:

public class UnionFind {private int[] parent;private int[] rank;public UnionFind(int n) {parent = new int[n];rank = new int[n];for (int i = 0; i < n; i++) {parent[i] = i;rank[i] = 0;}}public int find(int x) {if (x != parent[x]) {parent[x] = find(parent[x]); // 路径压缩}return parent[x];}public boolean union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX == rootY) {return false; // 已经在同一集合中}if (rank[rootX] > rank[rootY]) {parent[rootY] = rootX;} else if (rank[rootX] < rank[rootY]) {parent[rootX] = rootY;} else {parent[rootY] = rootX;rank[rootX]++;}return true;}public static void main(String[] args) {UnionFind uf = new UnionFind(5);uf.union(0, 1);uf.union(1, 2);System.out.println("Find 0: " + uf.find(0)); // 输出 0System.out.println("Find 1: " + uf.find(1)); // 输出 0System.out.println("Find 2: " + uf.find(2)); // 输出 0}
}

并查集的应用场景:

  1. 连通性问题:判断无向图的连通性,以及在有向图中找到强连通分量。
  2. 集合的合并:处理动态集合的合并问题,如网络中的动态分区。
  3. 路径查询:在迷宫或图中查找两个节点之间是否存在路径。

面试大厂题示例:

  1. 岛屿数量
    描述:给定一个由 ‘1’(陆地)和 ‘0’(水)组成的二维网格,每次移动都只能从陆地移动到相邻的陆地,计算网格中的岛屿数量。
    示例

    输入: grid = [["1","1","0","0","0"],["1","1","0","0","0"],["0","0","0","1","0"],["0","0","0","1","1"]
    ]
    输出: 3
    

    Java 源码:使用并查集的查找和合并操作来计算岛屿数量。

  2. 课程选修
    描述:给定一个课程列表和课程之间的先修课程关系,判断是否可能完成所有课程的学习。
    示例

    输入: courses = ["a", "b", "c", "d"], prerequisites = [["a", "b"], ["c", "d"]]
    输出: true
    

    Java 源码:使用并查集来检测是否存在环,如果存在环则无法完成所有课程。

  3. 社交网络好友关系
    描述:给定一个社交网络中的好友关系列表,判断任意两个人是否是朋友(直接或间接)。
    示例

    输入: friendships = [["alice", "bob"], ["bob", "carol"], ["alice", "carol"]]
    输出: true(alice 和 carol 是朋友)
    

    Java 源码:使用并查集来处理好友关系的查询,判断两个用户是否在同一个集合中。

这些题目和源码展示了并查集在解决实际问题中的应用。在面试中,能够根据问题的特点选择合适的算法并实现其解决方案是非常重要的。希望这些示例能够帮助你更好地准备面试!

题目 1:最小化恶意软件传播

描述
在一个社交网络中,每个用户都可能被恶意软件感染。编写一个程序,确定在最佳情况下,最少需要多少个用户来防止恶意软件的传播。每个用户可以选择感染0个、1个或无限多个其他用户。用户按照给定的顺序进行操作,每个用户的操作是独立的。

示例

输入: 
users = [["a", 1],["b", 2],["c", 3],["d", 4],["e", 5]
],
ops = [["a", "b"],["c", "a"],["d", "e"],["e", "a"]
]
输出: 2

Java 源码

public class MinMalwareSpread {public int minMalwareSpread(int[][] users, int[][] ops) {int n = users.length;int[] parent = new int[n + 1];for (int i = 0; i <= n; i++) {parent[i] = i;}for (int[] op : ops) {int a = find(parent, op[0]);int b = find(parent, op[1]);if (a != b) {parent[a] = b;}}int max = 0;for (int i = 0; i < ops.length; i++) {int a = find(parent, users[ops[i][0]][0]);int b = find(parent, users[ops[i][1]][0]);if (a == b) {return 1;}max = Math.max(max, Math.max(users[ops[i][0]][1], users[ops[i][1]][1]));}return Math.max(1, max);}private int find(int[] parent, int x) {if (parent[x] != x) {parent[x] = find(parent, parent[x]);}return parent[x];}public static void main(String[] args) {MinMalwareSpread solution = new MinMalwareSpread();int[][] users = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}};int[][] ops = {{1, 2}, {3, 1}, {4, 5}, {5, 1}};int result = solution.minMalwareSpread(users, ops);System.out.println("Minimum number of users to prevent spread: " + result);}
}

题目 2:无向图连通分量

描述
给定一个无向图,返回其所有连通分量的列表。连通分量是一个子图,其中任意两个顶点都是连通的。

示例

输入: 
graph = [[1, 2, 3],[0, 2],[1, 3],[2, 4],[3, 4]
]
输出: [[0, 1, 2, 3], [4]]

Java 源码

public class ConnectedComponents {public List<List<Integer>> connectedComponents(int[][] graph) {int n = graph.length;int[] parent = new int[n];for (int i = 0; i < n; i++) {parent[i] = i;}List<List<Integer>> components = new ArrayList<>();for (int i = 0; i < n; i++) {if (parent[i] == i) {List<Integer> component = new ArrayList<>();dfs(graph, i, parent, component);components.add(component);}}return components;}private void dfs(int[][] graph, int node, int[] parent, List<Integer> component) {component.add(node);for (int neighbor : graph[node]) {int p = find(parent, neighbor);if (p == neighbor) {dfs(graph, neighbor, parent, component);}}}private int find(int[] parent, int x) {if (parent[x] != x) {parent[x] = find(parent, parent[x]);}return parent[x];}public static void main(String[] args) {ConnectedComponents solution = new ConnectedComponents();int[][] graph = {{1, 2, 3}, {0, 2}, {1, 3}, {2, 4}, {3, 4}};List<List<Integer>> components = solution.connectedComponents(graph);System.out.println("Connected components: " + components);}
}

题目 3:判断是否为相同的树

描述
给定两个二叉树的根节点,判断它们是否是相同的树。两个二叉树相同,当且仅当它们的结构相同,并且所有对应位置的节点具有相同的值。

示例

输入: 
tree1 = [1, 2, 3],
tree2 = [1, 2, 3]
输出: true

Java 源码

public class IsSameTree {public boolean isSameTree(TreeNode tree1, TreeNode tree2) {if (tree1 == null && tree2 == null) {return true;}if (tree1 == null || tree2 == null) {return false;}return (tree1.val == tree2.val) &&isSameTree(tree1.left, tree2.left) &&isSameTree(tree1.right, tree2.right);}public static void main(String[] args) {IsSameTree solution = new IsSameTree();TreeNode tree1 = new TreeNode(1);tree1.left = new TreeNode(2);tree1.right = new TreeNode(3);TreeNode tree2 = new TreeNode(1);tree2.left = new TreeNode(2);tree2.right = new TreeNode(3);boolean result = solution.isSameTree(tree1, tree2);System.out.println("Trees are the same: " + result);}
}class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) { val = x; }
}

这些题目和源码展示了并查集在解决实际问题中的应用。在面试中,能够根据问题的特点选择合适的算法并实现其解决方案是非常重要的。希望这些示例能够帮助你更好地准备面试!

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

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

相关文章

学习基于pytorch的VGG图像分类 day2

注&#xff1a;本系列博客在于汇总CSDN的精华帖&#xff0c;类似自用笔记&#xff0c;不做学习交流&#xff0c;方便以后的复习回顾&#xff0c;博文中的引用都注明出处&#xff0c;并点赞收藏原博主. 目录 VGG网络搭建&#xff08;模型文件&#xff09; 1.字典文件配置 2.提取…

基于java+springboot+vue实现的农产品智慧物流系统(文末源码+Lw)23-239

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#…

Python创建现代GUI应用程序库之ttkbootstrap使用详解

概要 ttkbootstrap是一个基于Python的Tkinter库构建的,用于创建现代GUI应用程序。它结合了Tkinter的简洁性和Bootstrap框架的美观,提供了丰富的组件和样式,使开发人员能够快速构建美观、响应式的桌面应用程序。 安装 通过pip可以轻松安装ttkbootstrap: pip install ttkb…

CentOS 7详细介绍。

CentOS 7是CentOS项目发布的开源类服务器操作系统&#xff0c;自2014年7月7日正式发布以来&#xff0c;它已成为企业级Linux发行版本的佼佼者。CentOS 7不仅继承了其前身的优势&#xff0c;还在性能、安全性和易用性方面进行了显著的提升。以下是对CentOS 7的详细介绍。 一、C…

阿里云服务器北京地域多少钱?北京地域最新收费标准及便宜购买教程

阿里云服务器在国内有十几个地域可选&#xff0c;北京地域主要适合北方用户选择&#xff0c;2024年阿里云中国内地地域云服务器做了降价调整&#xff0c;因此收费标准也有所变化&#xff0c;本文为大家展示阿里云服务器北京地域最新的收费标准&#xff0c;以及在实际购买过程中…

JUC-线程的创建、运行与查看

创建和运行线程 Thread创建线程 Thread 创建线程方式&#xff1a;创建线程类&#xff0c;匿名内部类方式 start() 方法底层其实是给 CPU 注册当前线程&#xff0c;并且触发 run() 方法执行线程的启动必须调用 start() 方法&#xff0c;如果线程直接调用 run() 方法&#xff…

Spring day1

day01_eesy_01jdbc pom.xml<packaging>jar</packaging> <dependencies><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><!--依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-…

设计模式-接口隔离原则

基本介绍 客户端不应该依赖它不需要的接口&#xff0c;即一个类对另一个类的依赖应该建立在最小的接口上先看一张图: 类A通过接口Interface1 依赖类B&#xff0c;类C通过接口Interface1 依赖类D&#xff0c;如果接口Interface1对于类A和类C来说不是最小接口&#xff0c;那么类…

什么是多路复用器滤波器

本章将更深入地介绍多路复用器滤波器&#xff0c;以及它们如何用于各种应用中。您将了解到多路复用器如何帮助设计人员创造出更复杂的无线产品。 了解多路复用器 多路复用器是一组射频(RF)滤波器&#xff0c;它们组合在一起&#xff0c;但不会彼此加载&#xff0c;可以在输出之…

算法| ss 贪心

134.加油站455.分发饼干860.柠檬水找零2171.拿出最少数目的魔法豆 134.加油站 /*** param {number[]} gas* param {number[]} cost* return {number}*/ // 思路 // 判断: 汽油和 < 消耗和 return -1 // while循环遍历 从0开始, 计算是否有剩余 ,有就继续 没有就从下个点开…

Linux网络名称空间与网络协议栈:区别、联系与理解

在深入探讨Linux网络名称空间和网络协议栈之间的区别和联系之前&#xff0c;重要的是先明确这两个概念的定义。网络名称空间是Linux提供的一种虚拟化技术&#xff0c;允许在同一物理机器上运行的不同进程组拥有独立的网络环境&#x1f3e2;。而网络协议栈是操作系统用于实现网络…

React中的useMemo和useCallback:它们的区别及应用场景

React中的useMemo和useCallback&#xff1a;它们的区别及应用场景 1. useMemo&#xff1a;用于缓存计算结果2. useCallback&#xff1a;用于缓存函数3. 区别4. 应用场景4.1 useMemo的应用场景4.2 useCallback的应用场景 在React的Hooks API中&#xff0c;useMemo和useCallback是…

视频图像的两种表示方式YUV与RGB(3)

上篇文章介绍了YUV的采样格式&#xff0c;本篇重点介绍YUV的存储方式。接下来将用图形式给出常见YUV图像的存储方式&#xff0c;并在存储方式后面附有取样每个像素点YUV的数据方法&#xff0c;图中&#xff0c;Cb、Cr的含义等同于U、V。 YUYV为YUV422采样的存储格式中的一种&a…

探索 2024 年最佳编码自定义 GPT

如何利用GPT技术优化您的软件开发流程&#xff1f; 介绍 在快速发展的技术世界中&#xff0c;人工智能 (AI) 已成为创新的基石&#xff0c;特别是在编码和软件开发领域。 改变这一格局的人工智能工具之一是自定义 GPT。 这些先进的模型不仅彻底改变了我们的编码方式&#xff0c…

linux fixmap分析

本文基于Linux-4.19.125&#xff0c; ARM V7&#xff0c;dual core, MMU采用2级页表&#xff08;未开启LPAE&#xff09;。 1 为什么需要fixmap Linux内核启动过程中&#xff0c;经过汇编阶段后&#xff0c;mmu功能已经开启&#xff0c;后续只能通过虚拟地址来访问DDR&#x…

刷题日记——机试(3)

8.约瑟夫问题的实现 分析 创建一个队列和一个计数器&#xff0c;计数器初值为0&#xff0c;判断队列成员数是否为1&#xff0c;如果不是转3&#xff0c;是转6计数器每次1并且对k取余&#xff0c;然后将队首出队如果计数器值为0&#xff0c;那么回到2继续执行&#xff0c;如果不…

3.3.k8s搭建-rancher RKE2

目录 RKE2介绍 k8s集群搭建 搭建k8s集群 下载离线包 部署rke2-server 部署rke2-agent 部署helm 部署rancher RKE2介绍 RKE2&#xff0c;也称为 RKE Government&#xff0c;是 Rancher 的下一代 Kubernetes 发行版。 官网地址&#xff1a;Introduction | RKE2 k8s集群搭…

2024 年 3 月公链行业研报:比特币创新高、Meme 掀热潮、AI 板块露头角

作者&#xff1a;stellafootprint.network 数据来源&#xff1a;Footprint Analytics 公链研究页面 3 月份&#xff0c;加密市场表现强劲&#xff0c;比特币再创历史新高。以太坊价格稳步攀升&#xff0c;而坎昆升级则显著降低了交易成本。Solana 链上 Meme 热潮席卷而来&am…

【热门话题】 Fiddler:一款强大的Web调试代理工具——安装与使用详解

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Fiddler&#xff1a;一款强大的Web调试代理工具——安装与使用详解一、Fiddler的…

水位实时监测系统的工作原理

TH-SW3水位实时监测系统有多种应用场景&#xff0c;包括但不限于防汛、水文地质勘察、水资源管理等领域。例如&#xff0c;雷达水位监测站利用雷达微波技术进行水位测量&#xff0c;适用于河流、湖泊、水库等水域;积水监测站则主要使用在低洼地区&#xff0c;为城市内涝治理提供…