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

想要精通算法和SQL的成长之路 - 并查集的运用和案例(省份数量)

想要精通算法和SQL的成长之路 - 并查集的运用

  • 前言
  • 一. 并查集的使用和模板
    • 1.1 初始化
    • 1.2 find 查找函数
    • 1.3 union 合并集合
    • 1.4 connected 判断相连性
    • 1.5 完整代码
  • 二. 运用案例 - 省份数量

前言

想要精通算法和SQL的成长之路 - 系列导航

一. 并查集的使用和模板

先说一下并查集的相关知识点:

  • 含义:并查集,用于维护一组不相交的集合,支持合并两个集合和查询某个元素所属的集合。
  • 用途:解决图论、连通性问题和动态连通性等问题。

通俗一点,可以使用并查集的算法题目有哪些特征?

  • 需要将n个不同的元素划分为不相交的集合。
  • 开始的时候,每个元素自行成为一个集合,然后需要根据一定的顺序进行 合并
  • 同时还需要 查询 某个元素是否属于哪个集合。

因此并查集的基本操作可以包含两个:

  • 合并:将两个不相交的集合合并成一个集合。(将其中一个集合的根节点连接到另一个集合的根节点上)
  • 查找:根据某个元素,寻找到它所在集合的根节点。

1.1 初始化

首先我们考虑下,并查集里面需要有哪些数据结构:

  • 需要一个parent[]数组,用来存储每个元素对应的根节点。
  • 再来一个rank[]数组,代表以每个元素作为根节点,其所在集合的大小。即代表某个集合的深度。
  • 再来一个sum字段,代表当前的集合个数。
public class UnionFind {/*** 表示节点i的父节点*/private int[] parent;/*** 表示以节点i为根节点的子树的深度,初始时每个节点的深度都为0*/private int[] rank;private int sum;public UnionFind(int n) {parent = new int[n];rank = new int[n];// 初始时每个节点的父节点都是它自己for (int i = 0; i < n; i++) {parent[i] = i;}sum = n;}
}

1.2 find 查找函数

特征:

  • 入参:元素x
  • 要做的事情:不断地向上递归寻找这个x的根节点。
  • 递归终止条件:找到根节点。(根节点和元素本身一致)

代码如下:

public int find(int x) {while (x != parent[x]) {x = parent[x];}return x;
}

1.3 union 合并集合

特征:

  • 入参:元素xy
  • 要做的事情:分别找到这两个元素的根节点:rootXrootY
  • 如果俩元素的根节点是同一个,说明他们在一个集合当中,不需要任何操作。
  • 倘若两个元素的根节点不一样,根据两个集合的深度来判断。将深度小的那个集合,合并到深度大的集合中。同时更新对应的根节点和深度大小。

除此之外,我们还可以写一个简单的函数,用来判断两个元素是否处于同一个集合当中(或者是是否相连)

public void union(int x, int y) {int rootX = find(x);int rootY = find(y);// 如果两个元素的根节点一致,不需要合并if (rootX == rootY) {return;}// 如果根节点 rootX 的深度 > rootY。if (rank[rootX] > rank[rootY]) {// 那么将以rootY作为根节点的集合加入到rootX对应的集合当中rank[rootX] += rank[rootY];// 同时改变rootY的根节点,指向rootX。parent[rootY] = rootX;} else {// 反之rank[rootY] += rank[rootX];parent[rootX] = rootY;}
}

1.4 connected 判断相连性

/*** 判断两个节点是否在同一个集合中
*/
public boolean connected(int x, int y) {return find(x) == find(y);
}

1.5 完整代码

/*** @author Zong0915* @date 2023/10/4 下午2:52*/
public class UnionFind {/*** 表示节点i的父节点*/private int[] parent;/*** 表示以节点i为根节点的子树的深度,初始时每个节点的深度都为0*/private int[] rank;private int sum;public UnionFind(int n) {parent = new int[n];rank = new int[n];// 初始时每个节点的父节点都是它自己for (int i = 0; i < n; i++) {parent[i] = i;}sum = n;}public int find(int x) {while (x != parent[x]) {x = parent[x];}return x;}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);// 如果两个元素的根节点一致,不需要合并if (rootX == rootY) {return;}// 如果根节点 rootX 的深度 > rootY。if (rank[rootX] > rank[rootY]) {// 那么将以rootY作为根节点的集合加入到rootX对应的集合当中rank[rootX] += rank[rootY];// 同时改变rootY的根节点,指向rootX。parent[rootY] = rootX;} else {// 反之rank[rootY] += rank[rootX];parent[rootX] = rootY;}}/*** 判断两个节点是否在同一个集合中*/public boolean connected(int x, int y) {return find(x) == find(y);}
}

二. 运用案例 - 省份数量

原题链接
在这里插入图片描述
我们在并查集模板的基础上进行改造:

class UnionFind {private int[] rank;// 每个省份具有的城市数量private int[] parent;// 每个城市对应的根节点(省份)private int sum;// 省份的数量public UnionFind(int[][] isConnected) {int len = isConnected.length;// 初始化,省份数量和提供的城市数量一致sum = len;// 每个集合具有的城市数量为1rank = new int[len];parent = new int[len];Arrays.fill(rank, 1);// 根节点指向自己for (int i = 0; i < len; i++) {parent[i] = i;}}public int find(int x) {while (x != parent[x]) {x = parent[x];}return x;}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);// 如果两个元素的根节点一致,不需要合并if (rootX == rootY) {return;}// 如果根节点 rootX 的深度 > rootY。if (rank[rootX] > rank[rootY]) {// 那么将以rootY作为根节点的集合加入到rootX对应的集合当中rank[rootX] += rank[rootY];// 同时改变rootY的根节点,指向rootX。parent[rootY] = rootX;} else {// 反之rank[rootY] += rank[rootX];parent[rootX] = rootY;}// 合并成功,那么总集合数量要减1sum--;}
}

不过本题目当中,对于rank这个属性没有什么作用,最终看的是sum属性。因此大家可以把这个属性相关的给去除。

最后来看代码部分:

public int findCircleNum(int[][] isConnected) {// 初始化构造UnionFind unionFind = new UnionFind(isConnected);int len1 = isConnected.length;int len2 = isConnected[0].length;for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 如果是相连的,那么将城市 i 和 j 合并if (isConnected[i][j] == 1) {unionFind.union(i, j);}}}// 最后返回集合个数(即省份的个数)return unionFind.sum;
}

最终代码如下:

public class Test547 {public int findCircleNum(int[][] isConnected) {UnionFind unionFind = new UnionFind(isConnected);int len1 = isConnected.length;int len2 = isConnected[0].length;for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 如果是相连的,那么将城市 i 和 j 合并if (isConnected[i][j] == 1) {unionFind.union(i, j);}}}return unionFind.sum;}class UnionFind {private int[] rank;// 每个省份具有的城市数量private int[] parent;// 每个城市对应的根节点(省份)private int sum;// 省份的数量public UnionFind(int[][] isConnected) {int len = isConnected.length;// 初始化,省份数量和提供的城市数量一致sum = len;// 每个集合具有的城市数量为1rank = new int[len];parent = new int[len];Arrays.fill(rank, 1);// 根节点指向自己for (int i = 0; i < len; i++) {parent[i] = i;}}public int find(int x) {while (x != parent[x]) {x = parent[x];}return x;}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);// 如果两个元素的根节点一致,不需要合并if (rootX == rootY) {return;}// 如果根节点 rootX 的深度 > rootY。if (rank[rootX] > rank[rootY]) {// 那么将以rootY作为根节点的集合加入到rootX对应的集合当中rank[rootX] += rank[rootY];// 同时改变rootY的根节点,指向rootX。parent[rootY] = rootX;} else {// 反之rank[rootY] += rank[rootX];parent[rootX] = rootY;}sum--;}}
}

相关文章:

想要精通算法和SQL的成长之路 - 并查集的运用和案例(省份数量)

想要精通算法和SQL的成长之路 - 并查集的运用 前言一. 并查集的使用和模板1.1 初始化1.2 find 查找函数1.3 union 合并集合1.4 connected 判断相连性1.5 完整代码 二. 运用案例 - 省份数量 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 并查集的使用和模板 先说一下并查集…...

解决内网拉取企微会话存档代理问题的一种办法

问题&#xff1a;客户的服务都是内网的&#xff0c;不能直接访问外网&#xff1b;访问外网的话需要走kong网关才能出去。 会话存档官网说可以使用socket5、http方式拉取会话存档&#xff1b;我这边尝试了直接使用kong网关的ip和端口配置进去&#xff0c;是访问不了的 我后面就…...

二十二,加上各种贴图

使用pbr的各种贴图&#xff0c;albedo,金属度&#xff0c;ao,法线&#xff0c;粗糙度&#xff0c;可以更好的控制各个片元 1&#xff0c;先加上纹理坐标 texCoords->push_back(osg::Vec2(xSegment, ySegment)); geom->setVertexAttribArray(3, texCoords, osg::Array::BI…...

新版校园跑腿独立版小程序源码 多校版本,多模块,适合跑腿,外卖,表白,二手,快递等校园服务

最新校园跑腿小程序源码 多校版本&#xff0c;多模块&#xff0c;适合跑腿&#xff0c;外卖&#xff0c;表白&#xff0c;二手&#xff0c;快递等校园服务 此版本为独立版本&#xff0c;不需要** 直接放入就可以 需要自己准备好后台的服务器&#xff0c;已认证的小程序&#xf…...

SpringBoot banner 样式 自动生成

目录 SpringBoot banner 样式 自动生成 图案网站&#xff1a; 1.第一步创建banner.txt文件 2.访问网站Ascii艺术字实现个性化Spring Boot启动banner图案&#xff0c;轻松修改更换banner.txt文件内容&#xff0c;收集了丰富的banner艺术字和图&#xff0c;并且支持中文banner下…...

回收站里面删除的照片如何恢复?

现在拍照已经成为人们生活中的一种方式&#xff0c;照片为我们保留了许多珍贵而美好的回忆。大家通常会把重要的照片保存在硬盘里&#xff0c;但当不小心把照片移入回收站并彻底删除时&#xff0c;情况就有点糟糕了。那么&#xff0c;回收站里删除的照片还有办法恢复吗&#xf…...

Qt model/view 理解 2

这是我对 Qt 的 model/view 内容理解的第二篇 blog&#xff0c;在第一篇文章中&#xff0c;介绍 QTableView 和 QAbstractTableModel&#xff0c;实现显示了对数据源的显示&#xff0c;但是显示的格式和修改的模式都是按照 View 控件的自显示方式。在此&#xff0c;使用 Qt 自带…...

【LeetCode热题100】--114.二叉树展开为链表

114.二叉树展开为链表 方法一&#xff1a;对二叉树进行先序遍历&#xff0c;得到各个节点被访问到的顺序&#xff0c;利用数组存储下来&#xff0c;然后在先序遍历之后更新每个节点的左右节点的信息&#xff0c;将二叉树展开为链表 /*** Definition for a binary tree node.* …...

Java | Maven(知识点查询)

文章目录 Maven知识速查1. Maven概述2. Maven的作用3. Maven的下载4. Maven的环境配置5. Maven 的基础组成5.1 Maven仓库5.1.1 本地仓库配置&#xff1a;5.1.2 中央仓库配置&#xff1a;5.1.3 镜像仓库配置 5.2 Maven坐标 6. Maven项目6.1 手工创建Maven项目6.2 自动构建项目 7…...

Vmware 静态网络配置

概述 仅主机模式&#xff08;VMware1&#xff09;&#xff1a;使用host-only的方式是不能和外界通信的&#xff0c;只能够和本机的物理网卡通信 桥接&#xff08;VMnet0&#xff09;&#xff1a;使用桥接的方式使得自己的虚拟机和自己的真实机网卡在同一个网段 NAT&#xff0…...

【数据结构--八大排序】之希尔排序

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

Linux中生成so库的文件引用另一个so库问题的解决

文章目录 一、问题介绍二、问题解决 一、问题介绍 由于项目需求&#xff0c;需要将一个“编译时引用了另一个动态链接库”的文件&#xff08;名为main.c&#xff09;&#xff0c;再编译成一个动态链接库。 简要说明一下&#xff0c;即原本的项目代码里&#xff0c;包含main.c…...

EDI是连接原始电子商务和现代电子商务的纽带

EDI是连接原始电子商务和现代电子商务的纽带。 EDI&#xff08;Electronic Data Interchange&#xff0c;电子数据交换&#xff09;是一种电子通信技术&#xff0c;用于在不同组织之间以结构化和标准化的方式交换业务文档和数据。EDI使企业能够更有效地与供应商、客户和合作伙…...

星宿UI2.4资源付费变现小程序源码 支持流量主

第一个小程序为星宿小程序 目前是最新版2.0 搭建星宿需要&#xff1a;备用域名 服务器 微信小程序账号 功能&#xff1a;文章展示 文章分类 资源链接下载 轮播图 直接下载附件功能 很多 很适合做资源类分享 源码下载&#xff1a;https://download.csdn.net/download/m0_6604…...

代码随想录训练营二刷第四十六天 | 完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ

代码随想录训练营二刷第四十六天 | 518. 零钱兑换 II 377. 组合总和 Ⅳ 一、518. 零钱兑换 II 题目链接&#xff1a;https://leetcode.cn/problems/coin-change-ii/ 思路&#xff1a;完全背包求组合数&#xff0c;递推公式dp[j]dp[j-nums[i]]。 求组合数&#xff0c;物品在外…...

python安装第三方模块方法

正常情况下安装python第三方模块没啥说的&#xff0c;但是由于python安装模块默认是在外网下载安装&#xff0c;牵扯外网网速问题&#xff0c;所以可以配置下使用国内某镜像源来下载模块 python -m pip install xxxxxxxxxxx 和 pip install xxxxxxxxxx 的命令都可下载安装第三…...

广西小贷公司设立及小贷牌照申请政策要求

关于广西小额贷款公司设立及小贷牌照申请&#xff0c;依据《关于小额贷款公司试点的指导意见》&#xff08;银监发〔2008〕23号&#xff09;&#xff1b;《广西壮族自治区小额贷款公司管理办法》&#xff08;桂政发〔2009〕71号&#xff09;&#xff1b;《广西壮族自治区人民政…...

PyTorch应用实战二:实现卷积神经网络进行图像分类

文章目录 实验环境MNIST数据集1.网络结构2.程序实现2.1 导入相关库2.2 构建卷积神经网络模型2.3 加载MNIST数据集2.4 训练模型 附&#xff1a;系列文章 实验环境 python3.6 pytorch1.8.0 import torch print(torch.__version__)1.8.0MNIST数据集 MNIST数字数据集是一组手写…...

面试系列 - Java常见算法(二)

目录 一、排序算法 1、插入排序&#xff08;Insertion Sort&#xff09; 2、归并排序&#xff08;Merge Sort&#xff09; 二、图形算法 1、最短路径算法&#xff08;Dijkstra算法、Floyd-Warshall算法&#xff09; Dijkstra算法 Floyd-Warshall算法 2、最小生成树算法&…...

Cortex-A9 架构

一、Cortex-A 处理器运行模式 Cortex-A9处理器有 9中处理模式&#xff0c;如下表所示&#xff1a; 九种运行模式 在上表中&#xff0c;除了User(USR)用户模式以外&#xff0c;其它8种运行模式都是特权模式&#xff0c;在特权模式下&#xff0c;程序可以访问所有的系统资源。这…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...