Python描述数据结构之并查集实战篇

数据结构-第六期——并查集(Python) 数据结构——并查集 阅读详情

言

  有关并查集的知识及操作请参阅这篇博客。

  本篇章所涉及到的题目均来源于力扣(LeetCode),著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
  LeetCode中有关并查集的题目。

1. LeetCode547:朋友圈

  LeetCode第547题:朋友圈。

  题目 班上有 NNN 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 AAA 是 BBB 的朋友,BBB是 CCC 的朋友,那么我们可以认为 AAA 也是 CCC 的朋友。所谓的朋友圈,是指所有朋友的集合。
  给定一个 N∗NN * NN∗N 的矩阵 MMM,表示班级中学生之间的朋友关系。如果M[i][j]=1M[i][j] = 1M[i][j]=1,表示已知第 iii 个和 jjj 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
  提示

1. 1 <= N <= 200
2. M[i][i] == 1
3. M[i][j] == M[j][i]

  解题思路 如果把这个题目当做并查集来做,那么根据题目要求返回的就是最终合并成的子集合的个数,也就是数组中parent = -1的个数,即朋友圈的总数。
  所以这个题的做法就是,首先初始化我们的parent数组都为−1-1−1,长度为矩阵MMM的行数,也就是同学的个数;然后需要遍历整个矩阵,因为我们需要知道每个同学(每行)与其他同学(该行的所有列)是否是朋友(值为1),如果是朋友,我们就将这位朋友(列)划分到这个同学(行)的朋友圈中去,即parent数组中索引为对应列的值更改为行的值;最后统计parent数组中−1-1−1的个数。
M=⎡⎣110111011⎤⎦M=\begin{bmatrix}1 & 1 & 0 \\1 & 1 & 1 \\0 & 1 & 1 \\\end{bmatrix}M=⎣⎡​110​111​011​⎦⎤​  以上面这个矩阵为例:

  首先初始化parent数组:

同学012
parentparentparent-1-1-1

  然后开始遍历,第1行(即同学0),与同学0是朋友的是同学1,所以将parent数组中同学1的值改为0,即

同学012
parentparentparent-10-1

  然后遍历第2行(即同学1),与同学1是朋友的是同学0和同学2,因为我们查找可知,同学1是在同学0的朋友圈中,同学2是在同学1的朋友圈中,朋友的朋友是朋友,所以同学2也在同学0的朋友圈中,然后将parent数组中同学2的值也改为0,即

同学012
parentparentparent-100

  然后遍历第3行(即同学2),与同学2是朋友的是同学1,他们已经在同一个朋友圈里了,所以parent数组中的值不用更改,最终parent数组为

同学012
parentparentparent-100

  可以看出,parent数组中−1-1−1的个数为1,即这三位同学在同一个朋友圈中。
  代码如下:

class Solution(object):
    def Find(self, S, x):
        while S[x] != -1:
            x = S[x]
        return x

    def Union(self, S, root1, root2, Rank=None):
        x = self.Find(S, root1)
        y = self.Find(S, root2)
        if x != y:
            S[y] = x

    def findCircleNum(self, M):
        length = len(M)
        S = [-1] * length
        for row in range(length):
            for column in range(length):
                # 把自己和不是朋友的过滤掉
                if row != column and M[row][column] == 1:
                    self.Union(S, row, column)
        return S.count(-1)

  运行结果如下:

在这里插入图片描述

2. LeetCode200:岛屿数量

  LeetCode第200题:岛屿数量。

  题目 给你一个由'1'(陆地)和'0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。
  解题思路 这个题我用并查集做的,算法设计的不大好,遍历了两次数组。这里的每个网格(矩阵)上的点都是一个类,所以在初始化parent数组时,需要将二维网格上点的位置与parent数组上的位置一一对应,就是矩阵按行优先的方式转换成一维数组,具体可以参考这篇博客;然后遍历矩阵,将相邻的'1'归并到一起;最后统计每个集合的个数,就是找每个集合的BOSSBOSSBOSS,如果网格点对应parent数组的indexindexindex与它所属的集合号码一样,那该点就是集合的BOSSBOSSBOSS。
  代码如下:

class Solution(object):
    def Find(self, S, x):
        while S[x] != -1:
            x = S[x]
        return x

    def Union(self, S, root1, root2, Rank=None):
        x = self.Find(S, root1)
        y = self.Find(S, root2)
        if x != y:
            # S[y] = x
            # 按秩合并
            if Rank[x] > Rank[y]:
                S[y] = x
            elif Rank[x] < Rank[y]:
                S[x] = y
            else:
                # 谁并入谁都行, 并入到哪里, 哪里的秩就要加1
                S[y] = x
                Rank[x] += 1

    def numIslands(self, grid):
        if not grid:
            # LeetCode的这个操作太那啥了
            # 竟然放一个空数组进来
            return 0
        row = len(grid)
        column = len(grid[0])
        S = [-1] * (row * column)
        Rank = [1] * (row * column)
        for i in range(row):
            for j in range(column):
                if grid[i][j] == '1':
                    #           [i-1, j]
                    # [i, j-1]  [i, j]  [i, j+1]
                    #           [i+1, j]
                    for direction in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                        if 0 <= i+direction[0] < row and 0 <= j + direction[1] < column \
                                and grid[i + direction[0]][j + direction[1]] == '1':
                            self.Union(S, i * column + j, (i+direction[0]) * column + (j+direction[1]), Rank)
        count = 0
        for i in range(row):
            for j in range(column):
                if grid[i][j] == '1':
                    index = i * column + j
                    # 寻找集合的boss
                    if self.Find(S, index) == index:
                        count += 1
        return count

  运行结果如下:

在这里插入图片描述
  后来想想又对第二次遍历做了一个切片,然而效果并没有大的提升:

		count = 0
        for index in range(row * column):
            i = index // column
            j = index % column
            if grid[i][j] == '1':
                # 寻找集合的boss
                if self.Find(S, index) == index:
                    count += 1

3. LeetCode990:等式方程的可满足性

  LeetCode第990题:等式方程的可满足性。
  题目 给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程equations[i]的长度为4,并采用两种不同的形式之一:"a==b" 或 "a!=b"。在这里,aaa 和 bbb 是小写字母(不一定不同),表示单字母变量名。
  只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false。
  解题思路 这个题目是通过"=="号建立的连接关系,如果两者相等,说明这两个字符属于同一个集合;如果"!="号两边的字符在一个集合里面,那就说明这两个字符中间应该是"=="号,这时候就要返回false,否则返回true。
  代码如下:

class Solution(object):
    def Find(self, S, x):
        while S[x] != -1:
            x = S[x]
        return x

    def Union(self, S, root1, root2, Rank=None):
        x = self.Find(S, root1)
        y = self.Find(S, root2)
        if x != y:
            # S[y] = x
            # 按秩合并
            if Rank[x] > Rank[y]:
                S[y] = x
            elif Rank[x] < Rank[y]:
                S[x] = y
            else:
                # 谁并入谁都行, 并入到哪里, 哪里的秩就要加1
                # 这里是root2并入root1中
                S[y] = x
                Rank[x] += 1
                
    def equationsPossible(self, equations):
        # 将每个字母映射到数字
        S = [-1] * 26
        Rank = [1] * 26
        for equation in equations:
            if equation[1] == '=':
                self.Union(S, ord(equation[0]) - ord('a'), ord(equation[3]) - ord('a'), Rank)
        for equation in equations:
            if equation[1] == '!' and self.Find(S, ord(equation[0]) - ord('a')) == self.Find(S, ord(equation[3]) - ord('a')):
                return False
        return True

  运行结果如下:

在这里插入图片描述
  这个题感觉不用将字母映射也可以,只不过需要将parent数组换成一个字典,应该是可行的,有时间再试试。

结束语

  通过这几个题可以发现,并查集类的题目大致思路都一样,就是根据题目建立集合,然后将有连接的集合进行归并。我觉得难点就是集合归并后,如何选择合适的方法去处理它来得到正确的结果,这个方法的选择貌似就决定了算法的复杂性,继续加油(ง •̀_•́)ง

更多系列教程视频·教程点击视频获取:视频

python实现一个简单的并查集的示例代码 本篇文章主要介绍了python实现一个简单的并查集的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 立即下载

相关推荐

truetime2.0使用说明

truetime2.0使用说明1.1 truetime2.0工具箱的下载与安装1.2 truetime2.0工具箱的配置1.3 truetime2.0各模块的说明 注意,以下出现的地址本电脑MATLAB安装路径,请注意自己的MATLAB安装路径 1.1 truetime2.0工具箱的下载与安装 步骤1)没有工具箱的朋友可以 在可以在这个网站上免费申请下载http://www.control.lth.se/truetime/,里面有最新的版本。我用的是TrueTime 2.0 beta 1 步骤2)将

小六@sll 浊酒一杯 畅谈三千 清茶一壶 念游四海 4203

并查集的两种实现方式

先来看一道题目  假设现在有n个人,我们将其编号为1-n,在他们之间一些人有另外一个人作为上司,

半杯的博客 644

字符串相似度比较算法:Jaro–Winkler similarity的原理及实现

前言 在前面的文章中,笔者有对编辑距离以及Levenshtein距离进行详细的说明,其实levenshtein距离是编辑距离的其中一种定义,本文所说的Jaro距离是编辑距离的另外一种定义,它也是对两个字符串的相似度进行衡量,以得出两字符串的相似程度。下面我们一起来学习这个算法的原理以及实现吧。 标题算法定义 下面先说说Jaro distance(又称Jaro similarity),这是由Matt...

蓝天白云梦的csdn博客 1万+

并查集问题(一个很好用的数据结构)

一 并查集结构用来解决: 元素是否在集合中, 集合合并问题 最好给出了边的关系,不然就得向上下左右四个方向去找。 二 关键点: 每个节点都指向一个父节点 代表节点指向自己,一个集合只能拥有一个代表节点(类似树的根)。 三 如何判断是否两个元素属于同一集合? 向上寻找到代表节点,如果代表节点相同那么就在同一集合。 四 如何实现? 哈希表足以。C++哈希表 五 模板: 具体哈希表里面存储什么形式由具体情况决定,如果是int, int形式的话,用数组代替字典更好。 语法细节: STL11

weixin_38087754的博客 400

Jetson Orin NX 单目标跟踪算法实战

本文对比了NanoTrack和MixFormerV2两种目标跟踪算法在Jetson Orin NX边缘设备上的实际表现。通过天空小目标跟踪场景测试发现,NanoTrack虽然表征能力较弱,但具有目标身份一致性强、失败模式可控、计算负担小等优势,更适合作为边缘端默认算法。MixFormerV2则适用于高速运动等特定场景。实验数据显示NanoTrack在Orin NX上可达200FPS,远高于MixFormerV2的38-120FPS。建议先采用NanoTrack构建稳定系统,后续再评估复杂算法的适用性。

karmueo46的博客 626

大气层23.0.0整合包升级指南:解决unknow pkg1报错与双系统防误更新

自定义固件(CFW)通过劫持启动流程实现系统接管,其核心在于版本匹配与签名验证。当系统固件更新后,CFW必须同步更新核心文件与签名补丁,否则启动阶段会因版本不匹配而报错。双系统方案中,正版与虚拟系统固件独立,误更新正版系统会导致虚拟系统启动链断裂。正确做法是保持虚拟系统版本不低于正版,并严格对应大气层核心文件与签名补丁。本文围绕大气层23.0.0整合包,详解文件结构、安装顺序、Daybreak固件升级及防误更新策略,助你稳定运行自定义系统。

weixin_32075843的博客 456

关于 并查集(union find) 算法基本原理 以及 其 在分布式图场景的应用

二月的最后一篇水文…想写一些有意思的东西。 图计算或者存储场景中的 好友关系拓扑 分布式事务场景中冲突环中的 死锁检测部分

天行健,地势坤 2799

智能优化算法-北方苍鹰优化算法(NGO)(附源码)

北方苍鹰优化算法 (Northern Goshawk Optimizer, NGO) 是一种基于群体智能的元启发式优化算法,它模拟了北方苍鹰(Northern Goshawk)的捕食行为、领地行为以及社交互动,用于解决复杂的优化问题。总之,NGO作为一种新颖的优化算法,在处理复杂优化问题方面展现出了潜力。随着进一步的研究和应用,NGO有望成为解决实际问题的有效工具。

w971656545的博客 1362

矩形【并查集】

>Description 在一个平面上有n个矩形。每个矩形的边都平行于坐标轴并且都具有值为整数的顶点。我们用如下的方式来定义块。 每一个矩形都是一个块。 如果两个不同的矩形有公共线段,那么它们就组成了一个新的块来覆盖它们原来的两个块。 例子: 在图1中的矩形组成了两个不同的块。 写一个程序: 读入矩形的个数以及它们的顶点。 找出这些矩形形成的不同的块的个数。 >Input 在输入文...

//(^ o ^)// 350

RK3568-适配phy芯片ip101gri

复位时间查阅数据手册。

Paper_Love的博客 2645

AgentScope 2.0 源码解析-工具系统解读:从内置工具到权限管控的完整实践

本文深入解析AgentScope 2.0工具系统的完整架构,覆盖内置工具集(文件读写、命令执行、搜索匹配)、MCP协议集成(STDIO/HTTP双传输、客户端封装、工作空间网关)、工具包管理与动态分组、权限引擎的多级决策机制(危险路径保护、只读识别、模式控制),以及自定义工具开发流程。通过分层架构图和时序图直观展示组件协作关系,结合安全最佳实践与故障排除指南,为开发者提供从工具使用到安全管控的全链路参考。

program哲学 574

Python描述数据结构之图实战篇

本篇博文是前面学习的图的实战篇,通过在LeetCode上刷题,进而来巩固所学内容。

夏小悠的博客 1760

【OpenClaw企业级智能体实战】第11篇:制造业设备预测性维护实战——OpenClaw+DeepSeek+Prometheus从零搭建(附完整代码)

本文聚焦制造业设备预测性维护的核心痛点,基于OpenClaw v2026.2.1、DeepSeek智能诊断、Prometheus监控等工具,拆解“设备状态监控→智能故障诊断→预测性维护”三大核心场景。从技术原理、算法构建、实操流程到完整代码实现,提供“数据采集→模型训练→智能调度→自动处置”的全链路方案。方案遵循工业安全规范,采用“只读优先、权限最小化”原则,适配中小制造企业落地需求。通过虚拟案例验证,可使设备非计划停机时间下降65%、平均修复时间缩短47%,既适合新手快速入门,也为进阶读者提供架构优化思路

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 608

数据结构与Python算法——并查集

并查集是一种表示不相交集合的数据结构。并查集由一组彼此之间元素各不相同的集合组成,常用于表示一组不相交元素构成的动态集合。在并查集结构中,每个集合都有一个代表元素,用于表示该集合。代表元素可在集合内的元素中任意选取。

shame_Joker的博客 1629

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

python 数据结构与算法——并查集

并查集的原理及 python实现

颹蕭蕭 4265

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

玩转python:Python数据结构之并查集

并查集是一种高效的数据结构,特别适合处理集合合并与查找问题。连通性问题:判断节点是否连通。朋友圈问题:计算朋友圈数量。动态图连通性检测:实时判断节点连通性。最小生成树:Kruskal算法构建最小生成树。岛屿数量问题:计算二维网格中的岛屿数量。任务分组:按依赖关系分组任务。网络连接检测:检测网络是否连通。社交网络中的共同好友:查找共同好友。掌握并查集的操作和优化技巧,能够帮助你在实际项目中高效处理集合相关的问题。希望本文的案例能为你提供启发!

Luckstar2019的博客 815

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

数据结构之并查集:并查集的介绍与Python代码实现——18

并查集的介绍 并查集(Union-find)数据结构也称作合并查找集(Merge-find set)或者不相交集数据结构(disjoint-set data structure),它是一种记录了由一个或多个元素组成的不连续的分组的集合。并查集提供常数量的复杂度来添加、合并以及确定两个元素是否属于同一个集合。 并查集除了能够实现这些快速便利的操作,它在Krukal算法中寻找最小生成树的图也起着关键...

Moelimoe的博客 748

Python描述数据结构之森林篇

本篇章主要介绍森林的基本知识,包括森林的定义、树、森林与二叉树之间的转换、森林的遍历及并查集。

夏小悠的博客 3124

Python之并查集 洛谷 蓝桥杯

同时正在备战蓝桥杯 题解如有不足请多批评指正 大一双非本科在读 目标是进大厂 洛谷:亲戚关系 题目链接 问题分析:这是一道考察并查集的经典例题。 何为并查集?并查集是一种(树型)数据结构,用于处理一些不相交集合的合并及查询问题。 思想:用一个数组表示了整片森林,树的根节点唯一标识了一个集合,我们只要找到了某个元素的的树根,就能确定它在哪个集合里。 例如给出数组parent=[0,1,5,1,3,1],parent[i]代表结点i的父结点(很形象吧!?) 观察数组,我们知道:...

m0_62277756的博客 3210

【数据结构】 并查集 + 路径压缩与按秩合并 python

并查集(Union-Find 或 Disjoint Set Union, DSU)是一种数据结构,主要用于处理一些不相交集合的合并及查询问题。

查理零世的博客 2083

Python实现并查集

并查集是一种树型的数据结构,用于处理一些不交集的合并及查询问题。并查集用集合中的某个元素来代表一个集合,该元素称为集合的代表元;一个集合内的所有元素组织成以代表元为根的树形结构。

Explore 3057

python实现并查集

python实现并查集 以下为本人学习并查集的体会与总结。 并查集概念# 并查集也被称为不相交集数据结构。顾名思义,并查集主要操作是合并与查询,它是把初始不相交的集合经过多次合并操作后合并为一个大集合,然后可以通过查询判断两个元素是否已经在同一个集合中了。 并查集的应用场景一般就是动态连通性的判断,例如判断网络中的两台电脑是否连通,在程序中判断两个变量名是否指向同一内存地址等。 并查集的实现# 并查集的存储结构# 并查集逻辑上是森林,我们可以选出一个根节点作为代表,其他子结点指向...

sinat_61909096的博客 1850

并查集(python代码实现)

并查集是一种树型的数据结构,用于处理一些不相交集合的合并与查询问题。主要两种操作(合并和查询):实现: 一个集合构建一棵树,任选一个元素作为该集合的根节点; 建立pre数值记录每个元素的父节点,pre[当前节点]为父节点,根节点的父节点为自己本身。 给定元素关系,将一个集合的树变为另一个集合的子(将一个集合的根节点的父节点改为另一个集合的根节点),如:B的根节点等于A的根节点,这就可以将A和B两棵树合并为一棵树。 判断两个元素是否在同一个集合中: 从该

记录知识,学习分享 4911

并查集总结(python)

@toc 朋友圈问题 班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。 问题:输出朋友圈总数?最大朋友圈人数?所有的朋友圈等等。 并查集 Union Find 算法 ...

记录求学阶段的技术学习、项目实践与成长思考。 1万+
上一篇: Python爬虫练习 爬取网络小说保存到txt,这年头谁还付费看小说啊!
下一篇: Python 为什么没有 void 关键字?
pythonlaodi
博客等级 码龄6年 286粉丝 244原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值