java手写并查集算法应用拓展案例

Java手写并查集算法应用拓展案例

1. 并查集算法应用思路

并查集是一种用于处理不相交集合的数据结构,它支持合并(union)和查找(find)两种操作。并查集常用于解决集合合并、连通性问题等。
并查集算法的应用拓展案例主要分为以下几个步骤:

  1. 创建一个UnionFind类,该类包含一个数组parent和一个变量count,用于存储节点的父节点和记录集合的个数。

  2. 在UnionFind类中,实现find方法,用于查找节点的根节点,并进行路径压缩优化。

  3. 在UnionFind类中,实现union方法,用于合并两个节点的集合。如果两个节点已经处于同一个集合中,则说明存在环。

  4. 创建一个新的类,用于解决具体的问题。在这个类中,先创建一个UnionFind对象,初始化所有节点的父节点为自身,并将count设置为节点的个数。

  5. 遍历问题中的数据结构(如图的边、邻接矩阵等),根据具体问题的要求,调用UnionFind类中的union方法,合并两个节点的集合。

  6. 最后,调用UnionFind类中的getCount方法,获取最终的结果。具体问题的解决方法可能会有所不同,但整体的思路是相似的。

通过这样的步骤,可以将并查集算法应用到不同的问题中,实现高效的解决方案。

2. 案例一:判断无向图中是否存在环

class UnionFind {private int[] parent;public UnionFind(int n) {parent = new int[n];for (int i = 0; i < n; i++) {parent[i] = i;}}public int find(int x) {if (parent[x] != 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;}parent[rootX] = rootY;return true;}
}public class GraphCycleDetection {public boolean hasCycle(int[][] edges) {int n = edges.length;UnionFind uf = new UnionFind(n);for (int[] edge : edges) {int u = edge[0];int v = edge[1];if (!uf.union(u, v)) {return true;}}return false;}
}

代码解释:

  • UnionFind类是并查集的实现,其中parent数组用于存储每个节点的父节点。
  • find方法用于查找节点x的根节点,并进行路径压缩优化。
  • union方法用于合并两个节点x和y的集合,如果它们已经处于同一个集合中,则说明存在环。
  • GraphCycleDetection类用于判断无向图中是否存在环。通过遍历所有边,将每条边的两个节点进行合并操作,如果发现某条边的两个节点已经处于同一个集合中,则说明存在环。

3. 案例二:计算连通分量个数

class UnionFind {private int[] parent;private int count;public UnionFind(int n) {parent = new int[n];count = n;for (int i = 0; i < n; i++) {parent[i] = i;}}public int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]);}return parent[x];}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX == rootY) {return;}parent[rootX] = rootY;count--;}public int getCount() {return count;}
}public class ConnectedComponents {public int countComponents(int n, int[][] edges) {UnionFind uf = new UnionFind(n);for (int[] edge : edges) {int u = edge[0];int v = edge[1];uf.union(u, v);}return uf.getCount();}
}

代码解释:

  • UnionFind类的实现与前面的案例一相同,不同之处在于增加了count变量,用于记录当前的连通分量个数。
  • union方法中,每次合并两个节点的集合时,将count减1。
  • ConnectedComponents类用于计算无向图中的连通分量个数。通过遍历所有边,将每条边的两个节点进行合并操作,并更新count的值。

4. 案例三:求解朋友圈个数

class UnionFind {private int[] parent;private int count;public UnionFind(int n) {parent = new int[n];count = n;for (int i = 0; i < n; i++) {parent[i] = i;}}public int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]);}return parent[x];}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX == rootY) {return;}parent[rootX] = rootY;count--;}public int getCount() {return count;}
}public class FriendCircles {public int findCircleNum(int[][] M) {int n = M.length;UnionFind uf = new UnionFind(n);for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {if (M[i][j] == 1) {uf.union(i, j);}}}return uf.getCount();}
}

代码解释:

  • UnionFind类的实现与前面的案例二相同。
  • FriendCircles类用于求解朋友圈个数。通过遍历邻接矩阵,如果两个人是朋友关系,则将它们的节点进行合并操作,并更新count的值。

5.案例四:用于求解岛屿的数量问题

class UnionFind {private int[] parent;private int count;public UnionFind(char[][] grid) {int m = grid.length;int n = grid[0].length;parent = new int[m * n];count = 0;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == '1') {parent[i * n + j] = i * n + j;count++;}}}}public int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]);}return parent[x];}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX == rootY) {return;}parent[rootX] = rootY;count--;}public int getCount() {return count;}
}public class NumberOfIslands {public int numIslands(char[][] grid) {int m = grid.length;int n = grid[0].length;UnionFind uf = new UnionFind(grid);int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == '1') {for (int[] dir : directions) {int newRow = i + dir[0];int newCol = j + dir[1];if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n && grid[newRow][newCol] == '1') {uf.union(i * n + j, newRow * n + newCol);}}}}}return uf.getCount();}
}

代码解释:

  • UnionFind类的实现与前面的案例相同,不同之处在于构造函数的参数为二维字符数组grid,用于初始化并查集。
  • NumberOfIslands类用于求解岛屿的数量。通过遍历二维字符数组,如果当前位置为陆地,则将其与上下左右位置的陆地进行合并操作,并更新count的值。

这个代码用于解决岛屿的数量问题,其中岛屿被定义为被水包围的陆地,每个格子只能与上下左右四个方向的格子相连。通过并查集算法,可以高效地计算出岛屿的数量。

总结

本文介绍了并查集算法的三个拓展应用案例,并给出了完整的代码实现。这些案例分别用于判断无向图中是否存在环、计算连通分量个数以及求解朋友圈个数。并查集算法在解决这些问题时具有高效的特点,能够有效地提高算法的执行效率。
并查集算法是一种用于解决集合合并和查询问题的高效数据结构和算法。它通过维护一个树形结构来表示集合,并通过路径压缩和按秩合并等优化策略来提高算法的效率。

拓展总结

并查集算法的基本操作包括:

  • 初始化:将每个元素的父节点初始化为自身,表示每个元素都是一个独立的集合。
  • 查找:通过递归或迭代的方式查找元素所属的集合,找到根节点作为集合的代表。
  • 合并:将两个元素所属的集合合并为一个集合,即将一个根节点的父节点指向另一个根节点。

并查集算法的应用非常广泛,常见的应用场景包括:

  • 连通性问题:判断两个元素是否属于同一个集合,用于解决网络连接、社交网络关系等问题。
  • 最小生成树:用于求解图的最小生成树,例如Kruskal算法。
  • 图的连通分量:用于求解图的连通分量个数,例如求解岛屿的数量问题。
  • 环的检测:用于判断图中是否存在环,例如判断有向图中是否存在循环依赖。

总结起来,通过并查集算法,可以高效地解决一些集合合并和查询问题,特别适用于解决连通性问题和图论相关的应用。并查集算法的核心思想是将集合划分为不相交的子集,通过合并操作将不同的集合合并为一个集合,从而实现高效的查询和操作。

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

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

相关文章

在华为云服务器上CentOS 7安装单机版Redis

https://redis.io/是官网地址。 点击右上角的Download。 可以进入https://redis.io/download/——Redis官网下载最新版的网址。 然后在https://redis.io/download/页面往下拉&#xff0c;点击下图超链接这里。 进入https://download.redis.io/releases/下载自己需要的安装…

【C语言】自定义类型:结构体【结构体内存具详细】,枚举,联合

目录 一、结构体 1.结构的声明 2.特殊的声明 3.结构的自引用 4.结构体变量的定义和初始化 5.结构体内存对齐&#xff08;重点来了&#xff09; 6.为什么会存在内存对齐 7.修改默认对齐数 8.结构体传参 二、位段 1.什么是位段 2.位段的内存分配 3.位段的跨平台问题…

ajax day4

1、promise链式调用 /*** 目标&#xff1a;把回调函数嵌套代码&#xff0c;改成Promise链式调用结构* 需求&#xff1a;获取默认第一个省&#xff0c;第一个市&#xff0c;第一个地区并展示在下拉菜单中*/let pname axios({url: http://hmajax.itheima.net/api/province,}).t…

21天学会C++:Day11----运算符重载

CSDN的uu们&#xff0c;大家好。这里是C入门的第十一讲。 座右铭&#xff1a;前路坎坷&#xff0c;披荆斩棘&#xff0c;扶摇直上。 博客主页&#xff1a; 姬如祎 收录专栏&#xff1a;C专题 目录 1. 知识引入 2. 运算符重载 2.1 operator<() 2.2 operator() 2.3 o…

jvm中对象创建、内存布局以及访问定位

对象创建 Java语言层面&#xff0c;创建对象通常&#xff08;例外&#xff1a;复制、反序列化&#xff09;仅仅是一个new关键字即可&#xff0c;而在虚拟机中&#xff0c;对象&#xff08;限于普通Java对象&#xff0c;不包括数组和Class对象等&#xff09;的创建又是怎样一个过…

寄存器介绍

目录 寄存器的概念 寄存器工作原理 寄存器的状态 查看寄存器信息 寄存器复位 大空间寄存器复位 寄存器的概念 寄存器是计算机中一种临时存储数据的硬件设备&#xff0c;通常是高速缓存的一部分&#xff0c;用于存储、读取和操作计算机内部的数据。它们是计算机中最快的存…

小米华为,化干戈为玉帛!

近日来&#xff0c;手机圈又掀起了各大厂家推出新品的高潮。首先是华为Mate60的推出&#xff0c;其自研的麒麟9000S芯片瞬间点燃了国内手机市场&#xff0c;得到了国内甚至国外业界人士的认可和好评。 而近日网上盛传的小米创始人雷军的“愿意加入华为技术生态圈”的邀请&…

AtCoder ARC106 E Hall 定理 + 二分 + 容斥原理 + 高维前后缀和

题意 传送门 AtCoder ARC106 E Medals 题解 问题可以转化为每一天与职员之间的匹配问题&#xff0c;思路与 AtCoder ABC320 G Slot Strategy 2 (Hard) 类似。但二分图规模过大&#xff0c;直接求解最大匹配显然难以胜任。 根据 Hall 定理&#xff0c;若二分图一侧点集 S S…

JS操作字符串方法学习系列(4)-每天学习10个方法

目录 **字符串编码 (encodeURIComponent 和 decodeURIComponent)**:**字符串转换为日期 (Date Parsing)**:**字符串模板引擎 (Template Engines)**:**字符串替换所有匹配项 (replaceAll)**:**字符串分隔并限制 (String.prototype.split)**:**字符串转义字符 (Escape Characters…

Redis缓存实现及其常见问题解决方案

随着互联网技术的发展&#xff0c;数据处理的速度和效率成为了衡量一个系统性能的重要指标。在众多的数据处理技术中&#xff0c;缓存技术以其出色的性能优化效果&#xff0c;成为了不可或缺的一环。而在众多的缓存技术中&#xff0c;Redis 以其出色的性能和丰富的功能&#xf…

JDK jps命令复习

之前写过jdk命令工具的博文&#xff0c;下面复习jps命令&#xff1b; jps 是 Java Process Status Tool 的简称,它的作用是为了列出所有正在运行中的 Java 虚拟机进程和相关信息&#xff1b; jps 命令参数 -q 只输出进程 ID,省略主类的名称 -m 输出虚拟机进程启动时传递…

C#使用OpenCv(OpenCVSharp)图像轮廓凸包检测与绘制

本文实例演示C#语言中如何使用OpenCv(OpenCVSharp)对图像凸包轮廓检测与绘制。 找轮廓 public static void FindContours(InputArray image, out Point[][] contours, out HierarchyIndex[] hierarchy, RetrievalModes mode, ContourApproximationModes method, Point? of…

python经典百题之求前!的和

题目&#xff1a;求12!3!…20!的和 方法一&#xff1a; 使用for循环和阶乘函数计算每项的值&#xff0c;再将每项的值累加起来。 def factorial(n):if n 0:return 1else:return n * factorial(n-1)sum 0 for i in range(1, 21):sum factorial(i) * iprint(sum)优点&#…

Vue-DPlayer详细使用(包含遇到坑)

Vue-DPlayer&#xff1a;一个优秀的视频播放器组件 Vue-DPlayer是一个易于使用、高性能的基于Vue.js的视频播放器组件。如果你需要在你的Vue.js应用程序中实现视频播放功能&#xff0c;那么Vue-DPlayer就是一个很好的选择。在下面的文章中&#xff0c;我们将从以下四个方面对V…

AG35学习笔记(一):debug串口抓取模组log、debug串口测试AT指令、echo命令通过串口发送16进制数据

目录 一、概述二、抓取模组log2.1 硬件接口2.2 用户登录2.3 相关指令 三、测试AT指令3.1 查看端口3.2 进入模式 四、串口发16进制echo使用 一、概述 二、抓取模组log 在之前记录了通过USB&#xff0c;使用移远工具Qwinlog来抓取log&#xff08;3.3 抓取模组log&#xff09;。…

【Java】第一个Servlet程序

第一个Servlet程序 创建项目引入依赖手动创建必要的目录/文件编写代码打包程序部署验证程序是否正常工作 创建项目 选中maven 创建好项目后,观察左侧项目结构 引入依赖 当权代码需要使用servlet开发,而Java标准库中并没有servlet,此时就需要让maven能够把servlet的依赖获取…

子网的划分

强化计算机网络发现王道没有这一块的内容&#xff0c;导致做题稀里糊涂。于是个人调研补充。 子网划分是将一个大型IP网络划分成更小的子网&#xff0c;以实现更有效的网络管理和资源分配。 原因&#xff1a; 提高网络性能&#xff1a;子网划分可以减少广播域的大小&#xff…

成集云 | 用友NC集成旺店通ERP(旺店通主管库存)| 解决方案

源系统成集云目标系统 方案介绍 用友NC是用友NC产品的全新系列&#xff0c;是面向集团企业的世界级高端管理软件。它以“全球化集团管控、行业化解决方案、全程化电子商务、平台化应用集成”的管理业务理念而设计&#xff0c;采用J2EE架构和先进开放的集团级开发平台…

bootstrap柵格

.col-xs- 超小屏幕 手机 (<768px) .col-sm- 小屏幕 平板 (≥768px) .col-md- 中等屏幕 桌面显示器 (≥992px) .col-lg- 大屏幕 大桌面显示器 (≥1200px) 分为12个格子 -后面的1代表占12分子1也就是一份 1.中等屏幕 <div class"container-fluid a">&l…

Autojs 小游戏实践-潮玩宇宙开扭蛋

概述 最近在玩潮流宇宙&#xff0c;里面有扭蛋兔的一个玩法&#xff0c;开始有很多蛋&#xff0c;需要我们一个个点开&#xff0c;然后根据装备品质替换分解&#xff0c;潮流提供了自动开扭蛋功能&#xff0c;但是开到品质比自己装备好的时候回暂停&#xff0c;由于个人懒得看…