并查集的典型应用:统计省份数量
题目来源https://leetcode.com/problems/number-of-provinces/description/有 n 个城市其中一些彼此直接相连另一些则没有直接相连。如果城市 a 与城市 b 直接相连且城市 b 与城市 c 直接相连那么城市 a 与城市 c 间接相连。省份定义为一组直接或间接相连的城市且这组城市之外不包含其他与该组内城市相连的城市。给你一个 n x n 矩阵 isConnected其中 isConnected[i][j] 1 表示第 i 个城市和第 j 个城市直接相连而 isConnected[i][j] 0 表示二者不直接相连。请你返回矩阵中省份的总数量。【解】这道题是 LeetCode 547本质上就是求无向图的连通分量个数与并查集的经典用法完全吻合。解题思路问题转化有n个城市isConnected[i][j] 1表示城市i与j直接相连。省份 连通分量。求图中连通分量的总数。并查集建模初始时每个城市自成一个省份省份数量count n。遍历矩阵的上三角部分i j若isConnected[i][j] 1说明两个城市直接相连应属于同一个省份。调用union(i, j)若合并成功之前不在同一集合则当前省份数量减1。最终count就是省份的总数。复杂度分析时间O(n^2 * α(n))≈O(n^2)其中α(n)是反阿克曼函数可以视为常数。空间O(n)用于存储parent和rank数组。代码实现PythonclassUnionFind:def__init__(self,n):self.parentlist(range(n))self.rank[0]*n self.countn# 连通分量个数deffind(self,x):ifself.parent[x]!x:self.parent[x]self.find(self.parent[x])# 路径压缩returnself.parent[x]defunion(self,x,y):rootXself.find(x)rootYself.find(y)ifrootXrootY:returnFalse# 已在同一集合合并失败# 按秩合并ifself.rank[rootX]self.rank[rootY]:self.parent[rootX]rootYelifself.rank[rootX]self.rank[rootY]:self.parent[rootY]rootXelse:self.parent[rootY]rootX self.rank[rootX]1self.count-1# 成功合并连通分量减1returnTrueclassSolution:deffindCircleNum(self,isConnected:List[List[int]])-int:nlen(isConnected)ufUnionFind(n)foriinrange(n):forjinrange(i1,n):# 只需遍历上三角ifisConnected[i][j]1:uf.union(i,j)returnuf.count解题步骤解析第 3 行并查集类中额外维护count表示当前连通分量个数初始化为n。第 1117 行find采用递归写法同时进行路径压缩使得后续查找近似常数时间。第 1931 行union方法在成功合并两个不同集合时将count减 1其余逻辑与标准按秩合并一致。第 3638 行双重循环只遍历i j的部分避免重复和自环。若两城市直接相连则尝试合并。第 39 行最后直接返回uf.count即为省份总数。以下是使用 C 语言实现的并查集解法完全按照考研及算法题的标准写法编写包含路径压缩与按秩合并优化。#includestdlib.h// 查找操作路径压缩intfind(int*parent,intx){if(parent[x]!x)parent[x]find(parent,parent[x]);// 递归压缩路径returnparent[x];}// 合并操作按秩合并并通过指针修改连通分量计数voidunionSet(int*parent,int*rank,int*count,intx,inty){introotXfind(parent,x);introotYfind(parent,y);if(rootXrootY)return;// 已在同一集合不合并// 将较矮的树挂到较高的树下if(rank[rootX]rank[rootY]){parent[rootX]rootY;}elseif(rank[rootX]rank[rootY]){parent[rootY]rootX;}else{parent[rootY]rootX;rank[rootX];// 高度相等时树高增1}(*count)--;// 连通分量数减1}intfindCircleNum(int**isConnected,intisConnectedSize,int*isConnectedColSize){intnisConnectedSize;// 动态分配并查集所需数组int*parent(int*)malloc(n*sizeof(int));int*rank(int*)malloc(n*sizeof(int));// 初始化每个城市自成一个集合for(inti0;in;i){parent[i]i;rank[i]0;}intprovincesn;// 初始省份数量等于城市数量// 遍历矩阵的上三角部分避免重复for(inti0;in;i){for(intji1;jn;j){if(isConnected[i][j]1){unionSet(parent,rank,provinces,i,j);}}}intresultprovinces;// 释放内存free(parent);free(rank);returnresult;}说明函数签名严格按照 LeetCode 547 题的 C 接口要求int findCircleNum(int** isConnected, int isConnectedSize, int* isConnectedColSize)其中isConnectedSize为城市数量nisConnectedColSize为每行的列数数组可不用。并查集核心操作find递归实现路径压缩使树扁平化均摊近乎O(1)。unionSet按秩合并用rank记录树高上界避免树无故增高合并成功时将省份计数provinces减 1。复杂度分析时间O(n^2 · α(n))≈O(n^2)其中α(n)为反阿克曼函数可视为常数。空间O(n)仅需两个长度为n的数组。

相关新闻

苏州吴中区少儿机器人编程暑期班选哪家更靠谱?

苏州吴中区少儿机器人编程暑期班选哪家更靠谱?

苏州吴中区家长选少儿机器人编程暑期班?咋选才不踩坑? 暑假马上到了,苏州吴中区不少家长都在琢磨给娃报兴趣班,很多人瞄准了少儿机器人编程,既想让娃趁假期学点有用的技能,又怕踩坑选到不靠谱的机构&#x…

2026/6/26 6:42:52阅读更多 →
得理法律AI开放平台「类案检索报告skill」操作演示

得理法律AI开放平台「类案检索报告skill」操作演示

类案检索是律师最高频、最耗时的基础工作之一。得理开放平台推出的“类案检索报告”技能,通过深度语义理解与标准结构化报告生成,将这项工作从数小时压缩至几分钟。01背景与能力概述:从痛点解法到核心能力类案检索是律师最高频、最耗时的基础…

2026/6/26 6:42:52阅读更多 →
选对一杯速溶咖啡:为什么雀巢仍是日常提神的理性之选?

选对一杯速溶咖啡:为什么雀巢仍是日常提神的理性之选?

早上七点,你的咖啡不该将就 闹钟响第三遍,你冲进厨房想用一杯咖啡唤醒自己,却发现速溶粉结块、味道发涩,甚至喝完胃不舒服。这不是咖啡的问题,而是你没选对那一杯。在快节奏生活中,一杯靠谱的速溶咖啡不是妥…

2026/6/26 6:42:51阅读更多 →
热血少年:把理想“种”进日常,用一张图告别三分钟热度

热血少年:把理想“种”进日常,用一张图告别三分钟热度

理想谁都有,难的是天天做。这篇教程写给所有热血少年:怎么把口号变成看得见的计划,再用一张PPT把梦想“锚定”在每天的生活里,让坚持变得有迹可循。 你有没有过这种时候?深夜刷到一条励志视频,心里那团火“…

2026/6/26 16:17:08阅读更多 →
树莓派USB启动模式全解析:从OTP原理到刷机与SSD启动实战

树莓派USB启动模式全解析:从OTP原理到刷机与SSD启动实战

1. 项目概述:深入理解树莓派的USB启动模式对于很多树莓派玩家来说,SD卡是默认的启动媒介,但你是否知道,这个小巧的开发板还隐藏着通过USB启动的“第二生命线”?USB启动模式,这个在官方文档里一笔带过的功能…

2026/6/26 16:17:08阅读更多 →
85%效率提升:开源SchoolCMS教务系统如何重构学校数字化管理战略

85%效率提升:开源SchoolCMS教务系统如何重构学校数字化管理战略

85%效率提升:开源SchoolCMS教务系统如何重构学校数字化管理战略 【免费下载链接】schoolcms 中国首个开源学校教务管理系统、网站布局自动化、学生/成绩/教师、成绩查询 项目地址: https://gitcode.com/gh_mirrors/sc/schoolcms 作为中国首个开源学校教务管理…

2026/6/26 16:17:08阅读更多 →
【JAVA毕设源码分享】基于SpringBoot的学生学习成果展示平台的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringBoot的学生学习成果展示平台的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/6/26 16:17:08阅读更多 →
如何理解数据包在Linux内核中的完整运行:从网卡到应用程序

如何理解数据包在Linux内核中的完整运行:从网卡到应用程序

一、引言当你在浏览器中输入一个网址按下回车,到网页内容呈现在屏幕上,中间发生了什么?这个问题可以回答得很简单(“浏览器发请求,服务器返回数据”),也可以回答得非常深入。如果把问题缩小到网…

2026/6/26 16:17:08阅读更多 →
插板阀真空度稳定控制技术:阀门与真空泵的协同工作

插板阀真空度稳定控制技术:阀门与真空泵的协同工作

引言插板阀在工业生产尤其是半导体等高端领域中扮演着至关重要的角色。它能够精确控制流体的通断,在真空环境的构建与维持方面发挥着关键作用。而插板阀真空度的稳定控制直接影响着整个生产过程的稳定性和产品质量。若真空度控制不佳,可能会导致生产效率…

2026/6/26 16:12:07阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/26 11:03:22阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/26 4:15:25阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/26 9:29:01阅读更多 →
HPE (慧与) 服务器专用 ESXi 9 全套官方定制资源详解 + 完整部署升级教程

HPE (慧与) 服务器专用 ESXi 9 全套官方定制资源详解 + 完整部署升级教程

一、前言:企业运维痛点与资源价值自博通收购 VMware 之后,原 VMware 公开免费下载渠道全面关闭,企业运维人员想要获取适配 HPE 慧与服务器的 ESXi 9 原厂镜像,必须注册博通账号、绑定有效授权才能下载,无授权账号无法获…

2026/6/26 0:02:15阅读更多 →
Kotlin的@JvmStatic与@JvmField:与Java互操作的注解

Kotlin的@JvmStatic与@JvmField:与Java互操作的注解

Kotlin作为一门现代编程语言,与Java的互操作性一直是其核心优势之一。为了让Kotlin代码能够无缝对接Java,Kotlin提供了多种注解来优化互操作体验,其中JvmStatic和JvmField是两个关键注解。它们分别用于解决静态成员和字段在Java中的访问问题&…

2026/6/26 0:02:15阅读更多 →
深入解析musl libc中的mmap实现源码

深入解析musl libc中的mmap实现源码

最近在阅读musl libc源码时,发现其mmap的实现非常精妙,特分享给大家。 一、代码整体结构 这段代码实现了__mmap函数,并通过weak_alias导出为mmap。这是典型的musl libc风格——提供弱符号以便用户可以重写。 weak_alias(__mmap, mmap); 二…

2026/6/26 0:02:15阅读更多 →