并查集(Java实现)
创始人
2024-05-14 19:20:43
0

基本实现

任务:

  维护多个不相交的集合,支持两种操作:合并两个集合,查询一个元素所在的集合。

说明:

  维护一个森林,每一棵树都代表一个集合,树根元素为这个集合的代表元。利用数组father[]查询记录每个元素的父亲节点。

查询一个元素所处集合时,只需不断寻找父节点,即可找到该元素所处集合的代表元。

合并两个集合时,先找到两个集合代表元x,y,然后令father[x]=y即可。

优化:

  路径压缩,沿着树根的路径找到元素a所在集合代表元b后,对这条路径上的所有元素x,令father[a]=b;

  按rank启发式合并,对于每个集合维护一个rank值,每次将rank较小的集合合并到rank较大的集合,合并两个相同的集合时rank=rank+1。

  根据不同情况也可以添加集合大小等属性。


public class union_find {private int[] father;private int[] rank;//初始化public union_find(int n) {father = new int[n];rank = new int[n];for (int i = 0; i < n; i++) {father[i] = i;rank[i] = 1;}}//查询在那个集合int find(int v) {return father[v] = father[v] == v ? v : find(father[v]);}//合并void merge(int x, int y) {int a = find(x);int b = find(y);if (rank[a] < rank[b]) {father[a] = b;} else {father[b] = a;if (rank[a] == rank[b]) {rank[a]++;}}}}

例题

省份数量icon-default.png?t=MBR7https://leetcode.cn/problems/number-of-provinces/description/代码:

class Solution {public int findCircleNum(int[][] isConnected) {if(isConnected==null||isConnected.length == 0){return 0;}int n=isConnected.length;union_find uf=new union_find(n);for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if(isConnected[i][j]==1){uf.merge(i,j);}}}int cnt=0;for (int i = 0; i < n; i++) {if(uf.father[i]==i){cnt++;}}return cnt;}public class union_find {private int[] father;private int[] rank;//初始化public union_find(int n) {father = new int[n];rank = new int[n];for (int i = 0; i < n; i++) {father[i] = i;rank[i] = 1;}}//查询在那个集合int find(int v) {return father[v] = father[v] == v ? v : find(father[v]);}//合并void merge(int x, int y) {int a = find(x);int b = find(y);if (rank[a] < rank[b]) {father[a] = b;} else {father[b] = a;if (rank[a] == rank[b]) {rank[a]++;}}}}}

 

剑指 Offer II 119. 最长连续序列icon-default.png?t=MBR7https://leetcode.cn/problems/WhsWhI/description/

代码:

import java.util.HashMap;class Solution {public int longestConsecutive(int[] nums) {//存储下标和值Mapmap=new HashMap<>();union_find uf=new union_find(nums.length);for (int i = 0; i < nums.length; i++) {if(map.containsKey(nums[i]))continue;if(map.containsKey(nums[i]-1)){uf.merge(i,map.get(nums[i]-1));}if(map.containsKey(nums[i]+1)){uf.merge(i,map.get(nums[i] + 1));}map.put(nums[i], i);}int size=0;for (int i = 0; i < nums.length; i++) {if(uf.father[i]==i){size=Math.max(size,uf.size[i]);}}return size;}public class union_find {private int[] father;private int[] size;//初始化public union_find(int n) {father = new int[n];size= new int[n];for (int i = 0; i < n; i++) {father[i] = i;size[i] = 1;}}//查询在那个集合int find(int v) {return father[v] = father[v] == v ? v : find(father[v]);}//合并void merge(int x, int y) {int a = find(x);int b = find(y);if(a==b)return;father[a]=b;size[b]+=size[a];}}
}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...