当前位置: 首页 > 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;程序可以访问所有的系统资源。这…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...