数据结构与算法 -> 并查集
一、并查集概念
- 并查集是一种树形的数据结构,顾名思义,它用于处理一些不交集的合并及查询问题。 它支持两种操作:
- 查找(Find):确定某个元素处于哪个子集,单次操作时间复杂度 O(α(n)),即查询元素p和元素q是否属于同一组
- 合并(Union):将两个子集合并成一个集合,单次操作时间复杂度 O(α(n)),即合并元素p和元素q所在的组
- 以下是并查集的常用模板,需要熟练掌握。其中:
- n 表示节点数
- p 存储每个点的父节点,初始时每个点的父节点都是自己
- size 只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
- find(x) 函数用于查找 x 所在集合的祖宗节点
- union(a, b) 函数用于合并 a 和 b 所在的集合
二、并查集模板
1、模板一
// 并查集类。需要维护一个数组和两个方法,find()和union()
class UnionFind {
constructor(n) {
this.arr = []
// 初始默认为每个人是独立圈子,则他的父级就是他自身
for (let i = 0; i < n; i++) {
this.arr[i] = i
}
}
// 直到arr[x] === x,停止向上搜索
find(x) {
let arr = this.arr
while (arr[x] !== x) {
x = arr[x]
}
return arr[x]
}
// 路径压缩
union(x, y) {
let xFather = this.find(x)
let yFather = this.find(y)
if (xFather !== yFather) {
this.arr[xFather] = yFather
}
}
}
2、模板二
class UnionFind {
constructor(size) {
this.fa = []
this.size = size
this.init()
}
// 初始化 每个元素的父节点为自身
init() {
for(let i = 0; i < this.size; i++) {
this.fa[i] = i
}
}
// 递归找到根节点,同时进行路径压缩
find(x) {
if(x === this.fa[x]) {
return x
}
this.fa[x] = this.find(this.fa[x])
return this.fa[x]
}
// 合并 x, y 直到各自的根节点, 其中一个的指向另一个
merge(x, y) {
let fx = this.find(x)
let fy = this.find(y)
if(fx !== fy) {
this.fa[fx] = fy
}
}
// 获取集合数量
getCount() {
let count = 0
for(let i = 0; i < this.size; i++) {
if(this.fa[i] === i) {
count++
}
}
return count
}
}
3、模板三
// 这个并查集使用了一种叫做路径压缩的优化策略,可以有效减少查找操作的时间复杂度
class UnionFind {
constructor(n) {
this.count = n;
this.parent = [];
this.rank = [];
for (let i = 0; i < n; i++) {
this.parent[i] = i;
this.rank[i] = 1;
}
}
// 查找元素 p 所在的集合编号
find(p) {
if (p !== this.parent[p]) {
this.parent[p] = this.find(this.parent[p]);
}
return this.parent[p];
}
isConnected(p, q) {
return this.find(p) === this.find(q);
}
// 将元素 p 和元素 q 所在的集合合并
unionElements(p, q) {
const pRoot = this.find(p);
const qRoot = this.find(q);
if (pRoot === qRoot) {
return;
}
if (this.rank[pRoot] < this.rank[qRoot]) {
this.parent[pRoot] = qRoot;
} else if (this.rank[qRoot] < this.rank[pRoot]) {
this.parent[qRoot] = pRoot;
} else {
this.parent[pRoot] = qRoot;
this.rank[qRoot] += 1;
}
}
}
三、力扣例题
- 1971. 寻找图中是否存在路径 - 力扣(LeetCode)
- 130. 被围绕的区域 题解 - 力扣(LeetCode)
- 1361. 验证二叉树 题解 - 力扣(LeetCode)
- 785. 判断二分图 题解 - 力扣(LeetCode)
- 695. 岛屿的最大面积 题解 - 力扣(LeetCode)
四、PDF参考资料
百度网盘:https://pan.baidu.com/s/1FzPwQKEEoSeEWFX-7A104A?pwd=hcfr
数据结构与算法 -> 并查集的更多相关文章
- 模板——最小生成树kruskal算法+并查集数据结构
并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...
- 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集
最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...
- 近期公共祖先(LCA)——离线Tarjan算法+并查集优化
一. 离线Tarjan算法 LCA问题(lowest common ancestors):在一个有根树T中.两个节点和 e&sig=3136f1d5fcf75709d9ac882bd8cfe0 ...
- BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1123 Solved: 408 题目连接 http://w ...
- POJ1861 Network (Kruskal算法 +并查集)
Network Description Andrew is working as system administrator and is planning to establish a new net ...
- [学习笔记]可持久化数据结构——数组、并查集、平衡树、Trie树
可持久化:支持查询历史版本和在历史版本上修改 可持久化数组 主席树做即可. [模板]可持久化数组(可持久化线段树/平衡树) 可持久化并查集 可持久化并查集 主席树做即可. 要按秩合并.(路径压缩每次建 ...
- 图论 Kruskal算法 并查集
#include<iostream> #include<cstring> #include<string> #include<cstdio> #incl ...
- poj1251 Jungle Roads Kruskal算法+并查集
时限: 1000MS 内存限制: 10000K 提交总数: 37001 接受: 17398 描述 热带岛屿拉格里山的首长有个问题.几年前,大量的外援花在了村庄之间的额外道路上.但是丛林不断地超 ...
- 数据结构 之 并查集(Disjoint Set)
一.并查集的概念: 首先,为了引出并查集,先介绍几个概念: 1.等价关系(Equivalent Relation) 自反性.对称性.传递性. 如果a和b存在等价关系,记 ...
- luoguP3367 [模板]并查集
题目链接:https://www.luogu.org/problemnew/show/P3367 思路: 今天学了新算法——并查集,本题是简单的并查集题的模板. 核心思想是“递归+压缩路径”. 并查集 ...
随机推荐
- 【神经网络】softmax回归
前言 softmax回归为一种分类模型. 基本原理 由于softmax回归也是一种线性叠加算法,且需要输出离散值. 很自然地想到,可以取值最大的输出为置信输出.更进一步想到,如果有三个人A.B.C分别 ...
- 基于LZO的高性能无损数据解压缩IP
LZOAccel-D LZO Data Decompression Core/无损数据解压缩IP Core LZOAccel-D是一个无损数据解压缩引擎的FPGA硬件实现,兼容LZO 2.10标准. ...
- Codeforces Round #809 (Div. 2)C.Qpwoeirut And The City
题目大意: 当一栋楼比旁边两栋楼都高的时候,这栋楼为cool,对除了1和n以外的所有楼可以增加任意层,问在满足使最多的楼cool的前提下的花费最小. 当n为奇数的情况下: cool的楼实际上是固定的, ...
- java安全之CC1浅学(1)
前言 由于CC链还是比较复杂的,我们可以先看命令执行的部分payload之后再加上反序列化部分组成一个完整的payload 调试一 项目导入依赖,这里使用3.1版本 <!-- https://m ...
- Arch Linux 的安装
Arch Linux 的安装 作者:Grey 原文地址: 博客园:Arch Linux 的安装 CSDN:Arch Linux 的安装 版本 Arch Linux:2022.07.01 VMware ...
- 【云原生 · Kubernetes】Taint和Toleration(污点和容忍)
个人名片: 因为云计算成为了监控工程师 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying Taint和Toleration(污点和容忍) 概念 添加多个tainit(污点) 使用例子 ...
- win11如何双屏幕(1台主机2块显示器)
1.买两块大小相宜.刷新率相同的屏幕(如诺刷新率不一样可能后期造成卡顿现象) 2.用数据线将两块屏幕都接主机上(现在买新款屏幕基本上都会送双头HDMI线,老旧款式可能是VGA) HDMI款 VGA款 ...
- 【Devexpress】gridcontorl实现复制多个单元格
1.设置复制的时候不复制标题在OptionsClipboard.CopyColumnHeaders=false 2.设置选择的方式为按照单元格选择,以及可以多选 OptionsSelection.Mu ...
- js 传递路径参数到后台的转码和解码
在开发中遇到前端页面需要将一个附件的路径传递后台实现业务逻辑,但不进行编码一直报404的错误,上代码. 前端编码:JavaScript函数encodeURL() 说明:1 .encodeURL函数主要 ...
- 【Spring系列】- Spring循环依赖
Spring循环依赖 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目录 Spring循 ...