并查集(java)

article/2025/8/27 0:00:53

介绍 :

并查集属于数据结构的一种 是高等数据结构最基础的一部分,主要分为普通并查集 种类并查集以及带权并查集。它是一种用于管理元素所属集合的数据结构,这里的集合我们可以理解为一颗数 每个元素都是树上的有一个分叉,顺着分叉我们可以找到 这棵树的根 也就是这个集合里所有元素的“祖先”。

主要操作:

  1. 查找(find): 用于查找每棵树的根 也就是这个集合所有元素的祖先 这样就可以判断两个元素是否属于一个集合 就是看两个元素的祖先是否相同。

  1. 合并(merge):用于合并两颗树,将两个集合合并。

  1. 求大小(size):可以统计每个集合元素的个数。

底层实现&代码:

首先我们需要一个数组p 来表示每个元素的父亲 例如p[1]:表示1这个元素的根;由于初始时每个元素属于一个独立的整体 因此我们要交p[i]利用for 循环初始化 令p[i]=i;这样元素本身就是自己的父亲。

find 函数用来查找 每课树的根 这里我们规定了 根元素的根是他本身 因此我们利用 递归的思想顺着枝蔓找根 并且我们在递归中把每个元素的父亲都设置成了这棵树的根 ;如图所示:

merge函数用来合并两棵树 所谓合并 我们可以简单的理解为将树上的任意两个树枝连接起来 ;

这里我们直接将一颗树的根连接在另一颗树上;

例题1(蓝桥杯-#蓝桥幼儿园)

形如:朋友的朋友就是朋友 敌人的敌人是朋友 这样的字眼 或者语义 我们就应该首先想到 并查集这个数据结构;

题目描述

蓝桥幼儿园的学生是如此的天真无邪,以至于对他们来说,朋友的朋友就是自己的朋友。

小明是蓝桥幼儿园的老师,这天他决定为学生们举办一个交友活动,活动规则如下:

小明会用红绳连接两名学生,被连中的两个学生将成为朋友。

小明想让所有学生都互相成为朋友,但是蓝桥幼儿园的学生实在太多了,他无法用肉眼判断某两个学生是否为朋友。于是他起来了作为编程大师的你,请你帮忙写程序判断某两个学生是否为朋友(默认自己和自己也是朋友)。

输入描述

输出描述

输入输出样例

题意理解

首先我们可以从题目中得到 朋友的朋友也是朋友的字眼 题目中的红绳我们就可以理解为 并查集中的树枝连接着每个元素 那么这些元素都同属于一棵树 也就可以理解为 题目中的都是朋友的概念;前面已经介绍了find merge 函数 那么这题就迎刃而解了;

AC代码

//普通并查集 注意find函数 一个集相当于一棵树 一堆树组成一片森林 一棵树上有许多果子 find 函数用于找到这颗果子的根
import java.util.Scanner;//朋友的朋友就是我的朋友
public class Programming35_binghchaji {static int N=200010;static int[] p=new int[N];//代表这个数字的根public static void main(String[] args) {Scanner in=new Scanner(System.in);int n=in.nextInt();int m=in.nextInt();for(int i=1;i<=n;i++) p[i]=i;for(int i=0;i<m;i++){int num=in.nextInt();int f1=in.nextInt();int f2=in.nextInt();if(num==1){merge(f1,f2);}else{if(find(f1)==find(f2)) System.out.println("YES");elseSystem.out.println("NO");}}}static int find(int x){if(p[x] != x) p[x]=find(p[x]);return p[x];}static void merge(int x,int y){x=find(p[x]);y=find(p[y]);p[x]=y;//合并两棵树}
}

例题2(蓝桥杯 #蓝桥侦探)

题目描述

输入描述

输出描述

输入输出样例

题意理解&解题思想

例题1 是最基础的普通并查集 本题是种类并查集 与例题一不同的是我们可以从本题的字眼中得到 敌人的敌人是朋友 意思是一个与我不在一个大厅的大臣A说另一个大臣B与他不在一个大厅 那么照他所说大臣B必定与我一个在同一个大厅中 这种并查集我们不能简单的只开一个长度为N的数组了 我们要开一个长度为2*N的数组 那么多出来的i+N就用来表示i的对立面;

AC代码

package lanqiao.practice;//种类并查集 敌人的敌人是朋友 普通并查集做不到
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Programming36_binghchaji_2 {static int N=500010;static int M=500010;static int[] q=new int[2*N+10];public static void main(String[] args) throws IOException {BufferedReader br=new BufferedReader(new InputStreamReader(System.in));String[] s=br.readLine().split(" ");int n=Integer.parseInt(s[0]);int m=Integer.parseInt(s[1]);for(int i=1;i<=n*2;i++)q[i]=i;for(int i=0;i<m;i++){s=br.readLine().split(" ");int x=Integer.parseInt(s[0]);int y=Integer.parseInt(s[1]);if(find(x)!=find(y)){merge(x,y+n);merge(y,x+n);}else {System.out.println(x);break;}}}static int find(int x){if(q[x]!=x) q[x]=find(q[x]);return q[x];}static void merge(int x,int y){x=find(q[x]);y=find(q[y]);q[x]=y;}
}

例题3(蓝桥杯 #蓝桥部队)

题目描述

输入描述

输出描述

对于每个询问,输出一行表示答案;

输入输出样例

题意理解&解题思想

本题与上两题不同的是 本题多了几个要素 一个是要另外设置一个函数判断是否属于同一队列 那么就相当于判断两个元素 是否在同一颗树上 另外一个要素就是 要计算两个士兵之间的距离 那么我们可以理解为 计算一棵树上两个果实之间的距离 我们这里设置一个新的数组d 来表示元素[i]到根的距离 siz 来表示一棵树元素的多少 那么我们在合并元素的时候要注意 元素到根的距离会发生改变 ;这种并查集属于带权并查集

AC代码

package lanqiao.practice;//带权并查集
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Programming37_bingchaji_3 {public static void main(String[] args) throws IOException {BufferedReader br=new BufferedReader(new InputStreamReader(System.in));String[] s=br.readLine().split(" ");int n=Integer.parseInt(s[0]);int m=Integer.parseInt(s[1]);UF uf=new UF(n+10);for(int i=0;i<m;i++){s=br.readLine().split(" ");int op=Integer.parseInt(s[0]);int x=Integer.parseInt(s[1]);int y=Integer.parseInt(s[2]);if(op==1){uf.merge(y, x);}elseSystem.out.println(uf.dist(x, y));}}
}
//打包并查集class UF{int[] f,d,siz;//f用来统计一个数字的根 d用来统计siz用来统计这颗树的果zhi的多少public UF(int n){f=new int[n];d=new int[n];siz=new int[n];for(int i=1;i<n;i++)f[i]=i;Arrays.fill(siz,1);//初始时每棵树就根这一个元素;}int find(int x){if(x==f[x]) return f[x];int root =find(f[x]);d[x]+=d[f[x]];return f[x]=root;}boolean same(int x,int y){return find(x)==find(y);}boolean merge(int x,int y){x=find(x);y=find(y);if(x==y) return false;     d[y]+=siz[x];siz[x]+=siz[y];f[y]=x;return true;}int size(int x){return siz[find(x)];}int dist(int x,int y){if(!same(x,y)) return -1;return Math.abs(d[x]-d[y])-1;}}

总结

其实并查集难就难在要有一双发现并查集的眼睛 很多题目是不容易看出要用并查集来解决的;

并查集的代码可以打包成一个模板 以后我们发现要用到并查集的时候就可以直接套用模板,

实例化对象来调用函数。

打包代码

//打包并查集class UF{int[] f,d,siz;//f用来统计一个数字的根 d用来统计siz用来统计这颗树的果子的多少public UF(int n){f=new int[n];d=new int[n];siz=new int[n];for(int i=1;i<n;i++)f[i]=i;Arrays.fill(siz,1);//初始时每棵树就根这一个元素;}int find(int x){if(x==f[x]) return f[x];int root =find(f[x]);d[x]+=d[f[x]];return f[x]=root;}boolean same(int x,int y){return find(x)==find(y);}boolean merge(int x,int y){x=find(x);y=find(y);if(x==y) return false;     d[y]+=siz[x];siz[x]+=siz[y];f[y]=x;return true;}int size(int x){return siz[find(x)];}int dist(int x,int y){if(!same(x,y)) return -1;return Math.abs(d[x]-d[y])-1;}

http://chatgpt.dhexx.cn/article/i0pA9qgG.shtml

相关文章

C++并查集

文章目录 并查集的原理并查集的实现代码并查集的典型应用 并查集的原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用…

c++并查集(详细总结)

老话重谈&#xff0c;先看定义 并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合&#xff08;disjoint sets&#xff09;的合并及查询问题。常常在使用中以森林来表示。 首先得明白一些概念&#xff1a; 什么是树&#xff0c;什么是森林&#xff08;由树组成的叫…

Java——并查集

概念 当我们将多个元素分配到不同的集合中&#xff0c;这些集合有的是相关的&#xff0c;有的是不相关的。并查集就是用来查找两个元素是否在同一个集合中的 其主要实现方式是&#xff1a;将所有的元素以下标的形式存储在数组中。例如一共有十个人&#xff0c;那么就将这些人…

并查集Python版

以下来自于leetcode 使用数据结构&#xff1a;并查集 思路&#xff1a;由于相等关系具有传递性&#xff0c;所有相等的变量属于同一个集合&#xff1b;只关心连通性&#xff0c;不关心距离&#xff0c;因此很容易想到并查集。&#xff08;很容易嘛&#xff0c;反正我想不到&am…

并查集详解

文章目录 并查集一、简介1.定义2. 并查集的实现与优化 二、练习1.合并集合2.连通块中点的数量3. 食物链 三、总结 并查集 一、简介 1.定义 并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合的合并及查询问题&#xff08;即所谓的并、查&#xff09;。比如说&am…

带权并查集

带权并查集需要先理解一般的并查集&#xff0c;不明白的可自行先搜索有关内容 一般的并查集主要记录节点之间的链接关系&#xff0c;而没有其他的具体的信息&#xff0c;仅仅代表某个节点与其父节点之间存在联系&#xff0c;它多用来判断图的连通性&#xff0c;如下图所示&…

并查集,不就一并和一查?

什么是并查集 并查集这种数据结构&#xff0c;可能出现的频率不是那么高&#xff0c;但是还会经常性的见到&#xff0c;其理解学习起来非常容易&#xff0c;通过本文&#xff0c;一定能够轻轻松松搞定并查集&#xff01; 对于一种数据结构&#xff0c;肯定是有自己的应用场景和…

数据结构——并查集

并查集是一种数据结构&#xff0c;是树的一种应用&#xff0c;用于处理一些不交集&#xff08;一系列没有重复元素的集合&#xff09;的合并以及查询问题。并查集支持如下操作&#xff1a; 查询&#xff1a;查询某个元素属于哪个集合&#xff0c;通常是返回集合内的一个“代表…

并查集详解(C/C++)

并查集算法详解&#xff08;C&#xff09; 并查集基础并查集是什么&#xff1f;并查集的作用是什么&#xff1f;并查集的结构合并查询 代码实现优化1&#xff1a;避免退化&#xff08;按秩合并&#xff09;代码优化 优化2&#xff1a;路径压缩代码优化 最终代码实现复杂度分析经…

并查集及其应用

并查集的基本操作: 1.合并两个集合 2.查询两个元素的祖宗节点 扩展: 1.记录每个集合的大小 将集合大小绑定到代表元素节点上 就是并查集的思想 (不是每个元素都是正确的 但是代表元素是正确的) 2.记录每个点到根节点的距离 绑定到每个元素身上 因为每个元素到根节点的距离…

并查集(Union-Find) (图文详解)

文章目录 并查集基础知识定义C实现优化 精选算法题(Java实现)实现并查集交换字符串中的元素最长连续序列 - 字节面试常考连通网络的操作次数最大岛屿数量 (三种解法)省份数量冗余连接冗余连接Ⅱ情侣牵手(困难)移除最多的同行或同列石头等式方程的可满足性 结语 并查集基础知识 …

什么是 “并查集” ?

导语&#xff1a;并查集是一种精巧的算法&#xff0c;本身并不难理解&#xff0c;却很常用&#xff0c;在许多场景下都能找到并查集的身影。 本文作者封承成&#xff0c;年仅12岁&#xff0c;非常感谢他的投稿。 并查集是什么 并查集&#xff0c;是一种判断“远房亲戚”的算法。…

并查集(Disjoint Set)

目录 ❤️什么是并查集&#xff1f; &#x1f3b6;实现方法1 &#x1f414;实现方法2 &#x1f383;题目1 ❤️什么是并查集&#xff1f; 并查集是一种数据结构&#xff0c;用于处理一些不交集&#xff08;Disjoint sets&#xff0c;一系列没有重复元素的集合&#xff09;的…

并查集

参考 https://www.cnblogs.com/asdfknjhu/p/12515480.html https://www.bilibili.com/video/BV13t411v7Fs?p3 https://leetcode-cn.com/problems/number-of-provinces/solution/python-duo-tu-xiang-jie-bing-cha-ji-by-m-vjdr/ 一、基本概念 并查集是一种数据结构 并查集这…

并查集(详细解释+完整C语言代码)

目录 1概论 2.树的表现形式 3.代码实现 3.1创立集合 3.2合并 3.3查询 3.4路径压缩 第一个方法&#xff1a;查找时优化 第二个方法&#xff1a;合并时优化&#xff08;加权标记法&#xff09; 4.完整代码 4.1优化前 4.2优化后 1概论 并查集是一种十分精巧且实用的树形…

时间序列预测的一般步骤

一、ARIMA模型概述 ​​ ARMA模型就是AR和MA的简单结合&#xff0c;同时包含了历史数值项和错误项。由于AR和MA模型都对时间序列有平稳性要求&#xff0c;ARMA模型也存在这个限制&#xff0c;因此我们将其拓展到ARIMA模型&#xff0c;其可以解决非平稳性问题。引入的差分概念是…

时间序列预测算法总结

时间序列算法 time series data mining 主要包括decompose&#xff08;分析数据的各个成分&#xff0c;例如趋势&#xff0c;周期性&#xff09;&#xff0c;prediction&#xff08;预测未来的值&#xff09;&#xff0c;classification&#xff08;对有序数据序列的feature提…

基于深度学习的时间序列预测

# 技术黑板报 # 第十一期 推荐阅读时长&#xff1a;15min 前言 时间序列建模历来是学术和工业界的关键领域&#xff0c;比如用于气候建模、生物科学和医学等主题应用&#xff0c;零售业的商业决策和金融等。虽然传统的统计方法侧重于从领域专业知识层面提供参数模型&#xff0…

预测类问题中的时间序列预测模型

前言&#xff1a;时间序列预测模型适用于含有时间变量的模型预测&#xff0c;对中短期的预测有着较好的结果&#xff0c;对长期预测不适用。本文重点介绍ARIMA模型的原理及代码实现。 其他模型总结&#xff1a;​【Python】Python中的经典时间序列预测模型总结_风度78的博客-C…

Transformer 在时间序列预测中的应用

2017年&#xff0c;Google的一篇 Attention Is All You Need 为我们带来了Transformer&#xff0c;其在NLP领域的重大成功展示了它对时序数据的强大建模能力&#xff0c;自然有人想要把Transformer应用到时序数据预测上。在Transformer的基础上构建时序预测能力可以突破以往的诸…