当前位置: 首页 > news >正文

三行并查集

问题的提出

给定一个大小为n的集合{a, b, c, f, ...},其中存在k <= n个连通块,将该集合分成k个小的子集。
给定两个元素ij,如何在尽可能高效地进行以下两个操作

  • 判断两个元素是否在同一个连通块(即两元素连同)
  • 将两个元素所在的连通块连载一起,形成一个连通块

问题的解决

并查集,能在均摊O(1)的时间复杂度内解决上面的问题。
使用C++最简易的实现如下:

Init(n) { for(int i = 0; i < n; ++i) root[i] = i;}
Find(x) { return x == root[x] ? x : root[x] = find(root[x]); }
Union(x, y) {root[find(x)] = find(y); }

技巧一:路径压缩

如下的代码实现了路径压缩操作。

Find(x) { return x == root[x] ? x : root[x] = find(root[x]); }

[!question] 怎么理解路径压缩?
针对集合{1,2,3,4,5,6},若存在两个连通块:{1,2,3,4}{5,6}。其中{1,2,3,4}的存储形式是

graph RL4 --> 3 --> 2 --> 1

当调用Find(4)时,调用过程如下,

1<-2<-3<-4
F(4) := root[4] = F(3) = 1
F(3) := root[3] = F(2) = 1
F(2) := root[2] = F(1) = 1
F(1) := 1

最终,连通块会变成下面这个样子

graph RL4 --> 13 --> 12 --> 1

技巧二:按秩归并

秩,是指连通块的大小。
TODO

完整代码

class UnionFind:def __init__(self, n: int):# 一开始有 n 个集合 {0}, {1}, ..., {n-1}# 集合 i 的代表元是自己,大小为 1self._fa = list(range(n))  # 代表元self._size = [1] * n  # 集合大小self.cc = n  # 连通块个数# 返回 x 所在集合的代表元# 同时做路径压缩,也就是把 x 所在集合中的所有元素的 fa 都改成代表元def find(self, x: int) -> int:# 如果 fa[x] == x,则表示 x 是代表元if self._fa[x] != x:self._fa[x] = self.find(self._fa[x])  # fa 改成代表元return self._fa[x]# 判断 x 和 y 是否在同一个集合def is_same(self, x: int, y: int) -> bool:# 如果 x 的代表元和 y 的代表元相同,那么 x 和 y 就在同一个集合# 这就是代表元的作用:用来快速判断两个元素是否在同一个集合return self.find(x) == self.find(y)# 把 from 所在集合合并到 to 所在集合中# 返回是否合并成功def merge(self, from_: int, to: int) -> bool:x, y = self.find(from_), self.find(to)if x == y:  # from 和 to 在同一个集合,不做合并return Falseself._fa[x] = y  # 合并集合。修改后就可以认为 from 和 to 在同一个集合了self._size[y] += self._size[x]  # 更新集合大小(注意集合大小保存在代表元上)# 无需更新 _size[x],因为我们不用 _size[x] 而是用 _size[find(x)] 获取集合大小,但 find(x) == y,我们不会再访问 _size[x]self.cc -= 1  # 成功合并,连通块个数减一return True# 返回 x 所在集合的大小def get_size(self, x: int) -> int:return self._size[self.find(x)]  # 集合大小保存在代表元上# 作者:灵茶山艾府
# 链接:https://leetcode.cn/discuss/post/mOr1u6/
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
http://www.sczhlp.com/news/19572/

相关文章:

  • 一分钟建站seo快速上排名
  • 基于 Docker 的 LLaMA-Factory 全流程部署指南
  • 做网站心得体会关键词优化公司网站
  • 编程序可以做网站吗宁波网站推广大全
  • 专做山珍的网站seo外包品牌
  • 镇江做网站的公司百度本地推广
  • 整站seo哪家服务好微营销官网
  • 郑州网站建设公司如何新闻最新消息10条
  • 中国杭州官网网站在线优化工具
  • 湘潭网站建设方案咨询软件开发公司排行榜
  • 遵义网站建设有限公司网站推广渠道
  • wordpress加载ajax台州seo网站排名优化
  • 先做网站后付款如何做企业网页
  • 网站制作需要学多久可以引流推广的app
  • 昆明网站搜索引擎优化营销计划怎么写
  • 图片生成网站南京seo排名优化公司
  • 揭阳做网站站内推广的方法和工具
  • 普通银行卡可以做国外网站购物信用卡使用吗企业营销策划及推广
  • 手机网站开发多少钱怎么给自己的公司建立网站
  • web前端开发视频教学佛山百度网站排名优化
  • 江苏荣邦建设有限公司网站外贸网站建设报价
  • 淘宝网站链接怎么做要软文范例大全100
  • 佛山做网站多少钱提交百度收录
  • web个人网站怎么做淘宝关键词搜索排名
  • 深圳做网站jm3q竞价推广开户多少钱
  • 企业网站的形式有哪些品牌营销策略四种类型
  • 做网站有什么框架2021年关键词排名
  • 做网站诊断宁波网络营销推广咨询报价
  • 搜索网站建设推广优化电商网站怎样优化
  • 深圳网站建设厂家长岭网站优化公司