并查集练习—省份数量

news/2024/11/8 12:17:51/

上一篇中讲了并查集及其原理,在这篇文章中简单应用一下。如果对并查集不是很了解强烈建议先看上一篇。

题目:
有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。如果isConnected[i][j] = 1,则isConnected[j][i] = 1。

返回矩阵中 省份 的数量。

举例:
根据题目中最后一段所说,给定的n * n矩阵中,如果城市 i 和城市 j相连,则isConnected[i][j] = 1。
如果可以理解为一个2维数组中的行和列,是每个城市之间的连接关系。
在这里插入图片描述
如果所示,i为行数,j为列数。城市A和A本身之间默认是相连的为1,城市A与城市B相连,也为1,A与B相连,B也必定与A相连,所示BA也为1,城市AB之间构成了一大片的省份。城市C与AB都不相连,只有自己,所以CC为1,其余为0,此时图示中省份数为2。
在这里插入图片描述
如果ABC之间互不相连,则省份数量为3。
在这里插入图片描述
分析:
在这里插入图片描述

  1. 因为isConnected[i][j] = 1,则isConnected[j][i] = 1并且isConnected[i][i] = 1,所以矩阵一定是对称的。所以只需要遍历上半部分就可以(以从左上到右下的对角线为分界)。
  2. 以上图为例,AC相连,所以域中有{A,C},CA与AC域相同,不用管,B与其他两个不相连,单独为域{B},所以共两个省份{A,C},{B}。
  3. 将每个城市看做是一个样本,每个样本是一个独立的集合,如果isConnected[i][i] = 1,则进行合并。合并完后,看一共有几个集合。

实现方式与上一篇中介绍的HashMap方式有所不同,采用数组的形式,常数时间会照比Map更好一些(数组寻址比栈的压栈弹栈快)。

代码实现:

public static int findCircleNum(int[][] M) {int N = M.length;UnionFind unionFind = new UnionFind(N);for (int i = 0; i < N; i++) {for (int j = i + 1; j < N; j++) {if (M[i][j] == 1) {unionFind.union(i, j);}}}return unionFind.sets;}public static class UnionFind {//i位置的parent是parent[i]private int[] parent;//i所在集合大小为size[i]//size[i]是代表节点才有意义,否则无意义private int[] size;//容器,帮助使结构扁平化private int[] help;//集合个数private int sets;public UnionFind(int N) {parent = new int[N];size = new int[N];help = new int[N];sets = N;for (int i = 0; i < N; i++) {parent[i] = i;size[i] = 1;}}//从index开始,找到代表节点,并进行路径压缩public int findParent(int index) {int num = 0;while (index != parent[index]) {help[num++] = index;index = parent[index];}for (int i = 0; i < num; i++) {help[i] = parent[index];}return index;}public boolean isSameSet(int i, int j) {return findParent(i) == findParent(j);}public void union(int i, int j) {int iParent = findParent(i);int jParent = findParent(j);if (iParent != jParent) {if (size[i] >= size[j]){size[i] += size[j];parent[jParent] = iParent;}else{size[j] += size[i];parent[iParent] = jParent;}sets--;}}}

http://www.ppmy.cn/news/1007906.html

相关文章

三数之和 LeetCode热题100

题目 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 …

设计模式——面向对象的7大设计原则

1.单一职责原则 一个类中最好只放一种类型的方法&#xff0c;比如Dao中只有和数据库交互相关的代码。实现高内聚&#xff0c;低耦合。 2.开闭原则 对外拓展开放&#xff0c;对内修改关闭&#xff0c;有新的需求时不要修改已有代码&#xff0c;而是添加新的代码&#xff0c;比…

合宙Air724UG LuatOS-Air script lib API--ntp

ntp Table of Contents ntp ntp.timeSync(period, fnc, fun) ntp 模块功能&#xff1a;网络授时. 重要提醒&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 本功能模块采用多个免费公共的NTP服务器来同步时间 并不能保证任何时间任何地点都能百分…

分类预测 | MATLAB实现WOA鲸鱼算法同步优化特征选择结合支持向量机分类预测

分类预测 | MATLAB实现WOA鲸鱼算法同步优化特征选择结合支持向量机分类预测 目录 分类预测 | MATLAB实现WOA鲸鱼算法同步优化特征选择结合支持向量机分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现WOA鲸鱼算法同步优化特征选择结合支持向量机分类预测…

关于HIVE的分区与分桶

1.分区 1.概念 Hive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录&#xff0c;每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择查询所需要的分区&#xff0c;这样的查询效率会提高很多 个人理解白话:按表中或者自定义的一个列,对数据进…

Vue 简版文件预览笔记

简版文件预览笔记 调用方法 <script lang"ts" setup>import {exportFileData,preViewFile,} from /xxx/tools.ts;import {fileDownload,} from /api/xxx/xx;// 预览方法const handleViewBtn () > {const filePath 获取预览地址;const urlFormat 获取预…

vscode无法连接远程服务器的可能原因:远程服务器磁盘爆了

vscode输入密码后一直等待&#xff0c;无法进入远程服务器终端&#xff1a; 同时Remote-SSH输出包含以下内容 在日志中的以下几个部分&#xff1a; [17:15:05.529] > wget download failed 这表明VS Code尝试在远程服务器上下载VS Code服务器时失败了。> Cannot write…

iOS 解析闪退信息

记录通过xxx.app.dSYM文件解析16进制闪退信息 因为运营给到的闪退信息是.txt文本&#xff0c;而不是导出的.carsh文件&#xff0c;同时给到了出包的xxx.app.dsYM文件,为了查看具体的闪退日志&#xff0c;只能通过命令行转才能查看原因。(如果同时有给到.crash文件、.app文件、…