并查集Python版

article/2025/8/27 0:02:45

以下来自于leetcode

使用数据结构:并查集

  • 思路:由于相等关系具有传递性,所有相等的变量属于同一个集合;
  • 只关心连通性,不关心距离,因此很容易想到并查集。(很容易嘛,反正我想不到)

并查集

  • 「并查集」用于判断一对元素是否相连,它们的关系式动态添加的,这一类问题叫做「动态连通性」问题;
  • 主要支持「合并」与「查询是否在同一个集合」操作;
  • 底层结构是「数组」或者「哈希表」,用于表示「节点」指向「父节点」,初始化时指向自己;
  • 「合并」就是把一个集合的根节点指向另一个集合的根节点,只要根节点一样,就表示在同一个集合里;
  • 这种表示「不相交集合」的方法称之为「代表元法」,以每个结点的根节点作为一个集合的「代表元」。
  • 「路径压缩」和「按秩压缩」一起使用的时候,难以维护「秩」准确的定义,但依然具有参考价值。
  • 同时使用「路径压缩」和「按秩合并」,「合并」「查询」的时间复杂度接近O(1);
  • 「并查集」的时间复杂度分析,可以在互联网上搜索相关资料学习;
  • 一般而言,「路径压缩」和「按秩合并」使用其中一个即可。

并查集的应用

  • 最小生成树:Kruskal算法

并查集的优化1:路径压缩(Path Compression)

并查集的优化2:按「秩」(Rank)合并

  • 「按秩合并」是指在合并的过程中,使得「高度」更低的树的根节点指向「高度」更高的根节点,以避免合并以后的树高度增加;
    990.等式方程的可满足性。

以下来自于算法视频笔记
并查集(union & find)是一种树型的数据结构,用于处理一些不交集(Disjoint Sets)的合并及查询问题。
Find:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。
Union:将两个子集合并成同一个集合。
在这里插入图片描述

在生活中的例子

  1. 小弟——>老大
  2. 帮派识别
  3. 两种优化方式

初始化

在这里插入图片描述
在这里插入图片描述

并查集原始版代码

class baseUnion:# n为节点大小def __init__(self, n):self.parent = list(range(n))  # 从0开始# 查找(递归)def recursion_find(self, index):if self.parent[index] != index:self.parent[index] = self.find(self.parent[index])return self.parent[index]# 查找(迭代,效率更高)def iteration_find(self, index):root = indexwhile root != self.parent[root]:root = self.parent[root]return self.parent[root]  # 或者返回root# 连接def union(self, index1, index2):self.parent[self.iteration_find(index1)] = self.recursion_find(index2)

并查集优化一

在这里插入图片描述

class rank_union:# n为节点大小def __init__(self, n):self.parent = list(range(n))  # 从0开始self.rank = [0] * n# 查找和基本并查集不变# 查找(迭代,递归也可以)def find(self, index):root = indexwhile root != self.parent[root]:root = self.parent[root]return self.parent[root]  # 或者返回root# 连接def union(self, index1, index2):rootx = self.find(index1)rooty = self.find(index2)# 如果不在同一连通分量里进行连接if rootx != rooty:if self.rank[rootx] > self.rank[rooty]:self.parent[rooty] = rootxelif self.rank[rootx] < self.rank[rooty]:self.parent[rootx] = rootyelse:  # 随便选一个self.parent[rooty] = rootxself.rank[rootx] += 1

并查集优化二

优化二效率更高,直接指向根节点,不需要添加rank属性。
在这里插入图片描述

# 效率更高,不需要添加rank属性(实际情况不明显)
class path_compression_union:# n为节点大小def __init__(self, n):self.parent = list(range(n))  # 从0开始self.rank = [0] * n# 查找和基本并查集不变# 查找(迭代,递归也可以)def find(self, index):root = indexwhile root != self.parent[root]:  # 找根节点root = self.parent[root]while index != self.parent[index]:  # 路径压缩tmp = self.parent[index]self.parent[index] = rootindex = tmpreturn self.parent[root]  # 或者返回root# 连接def union(self, index1, index2):self.parent[self.find(index1)] = self.find(index2)

实战题目

  • number-of-islands
  • friend-circles

岛屿个数

方法一:染色问题(FloodFill)
A.遍历节点:

if node == '1':count++;将node和附近节点->'0'; # DFS BFS
else:不管;

具体代码:

class Solution(object):self.dx = [-1,1,0,0]self.dy = [0,0,-1,1]def numIslands(self,grid):if not grid or not grid[0]: return 0self.max_x = len(grid); self.max_y = len(grid[0]); self.grid = grid;self.visited = set()return sum([self.floodfill_DFS(i,j) for i in range(self.max_x) for j in range(self.max_y)])def floodfill_DFS(self,x,y):if not self._is_valid(x,y):return 0self.visited.add((x,y))for k in range(4):self.floodfill_DFS(x + dx[k],y + dy[k])return 1def floodfill_BFS(self,x,y):if not self._is_valid(x,y):return 0self.visited.add((x,y))queue = collections.deque()queue.append((x,y))while queue:cur_x,cur_y = queue.popleft()for i in range(4):new_x,new_y = cur_x + dx[i],cur_y + dy[i]if self._is_valid((new_x,new_y))self.visited.add((new_x,new_y))queue.append((new_x,new_y))return 1def _is_valid(self,x,y):if x < 0 or x >= self.max_x or y < 0 or y >= self.max_y:return Falseif self.grid[x][y] == '0' or ((x,y) in self.visited):return Falsereturn True

方法二:并查集
A.初始化:针对’1’结点
B.遍历所有节点,相邻节点合并;'1’合并,'0’不管
C.遍历(找不同的parents,可以在第二步进行统计)

class UnionFind(object):def __init__(self,grid):m,n = len(grid),len(grid[0])self.count = 0self.parent = [-1] *(m+n)self.rank = [0] * (m+n)for i in range(m):for j in range(n):if grid[i][j] == '1':self.parent[i*n + j] = i*n + j # 二维坐标转为一维self.count += 1 # 初始化加一def find(self,i): # 递归if self.parent[i] != i:self.parent[i] = self.find(self.parent[i])return self.parent[i]def union(self,x,y):rootx = self.find(x)rooty = self.find(y)if rootx != rooty:if self.rank[rootx] > self.rank[rooty]:self.parent[rooty] = rootxelif self.rank[rootx] < self.rank[rooty]:self.parent[rootx] = rootyelse:self.parent[rooty] = rootxself.rank[rootx] += 1self.count -= 1 # 合并减一class Solution(object):def numIslands(self,grid):if not grid or not grid[0]:return 0uf = UnionFind(grid)directions = [(0,1),(0,-1),(-1,0),(1,0)]m,n = len(grid),len(grid[0])for i in range(m):for j in range(n):if grid[i][j] == '0':continuefor d in directions:nr,nc = i + d[0],j + d[1]if nr >= 0 and nc >= 0 and nr < m and nc < n and grid[nr][nc] == '1':uf.union(i*n+j,nr*n+nc)return uf.count

朋友圈

可以转化为岛屿问题


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

相关文章

并查集详解

文章目录 并查集一、简介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的基础上构建时序预测能力可以突破以往的诸…

【推荐收藏】11种比较常用的时间序列预测模型

时间序列及其预测是日常工作中建模&#xff0c;分析&#xff0c;预测的重要组成部分。 本文我们将从0开始介绍时间序列的含义&#xff0c;模型及其分析及其常用的预测模型。 文章目录 交流时间序列定义时间序列预测模型与方法原始数据朴素法简单平均法移动平均法指数平滑法一次…

时间序列预测的20个基本概念总结

1、时间序列 时间序列是一组按时间顺序排列的数据点 比如&#xff1a; 每小时的气压每年的医院急诊按分钟计算的股票价格 2、时间序列的组成部分 时间序列数据有三个主要组成部分。 趋势季节性残差或白噪声 3、趋势 在时间序列中记录的长期缓慢变化/方向。 4、季节性 …

时间序列-预测(Forcasting):时间序列预测算法总结

一、背景介绍 绝大部分行业场景,尤其是互联网、量化行业,每天都会产生大量的数据。金融领域股票价格随时间的走势;电商行业每日的销售额;旅游行业随着节假日周期变化的机票酒店价格等; 我们称这种不同时间收到的,描述一个或多种特征随着时间发生变化的数据,为时间序列…

时间序列预测 | ARMA应用指南

ARMA可谓是时间序列最为经典常用的预测方法&#xff0c;广泛应有于涉及时间序列的各个领域。ARMA模型自出道以来&#xff0c;出场次数不可胜数。想必大家也都不陌生&#xff0c;常学常新&#xff0c;我们今天不妨再来回顾一遍&#xff5e;。 ARMA全称Autoregressive moving ave…