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

基于C#实现并查集

一、场景

有时候我们会遇到这样的场景,比如:M={1,4,6,8},N={2,4,5,7},我的需求就是判断{1,2}是否属于同一个集合,当然实现方法有很多,一般情况下,普通青年会做出 O(MN)的复杂度,那么有没有更轻量级的复杂度呢?并查集就是用来解决这个问题的。

二、操作

从名字可以出来,并查集其实只有两种操作,并(Union)和查(Find),并查集是一种算法,所以我们要给它选择一个好的数据结构,通常我们用树来作为它的底层实现。

2.1、节点定义

 #region 树节点/// <summary>/// 树节点/// </summary>public class Node{/// <summary>/// 父节点/// </summary>public char parent;/// <summary>/// 节点的秩/// </summary>public int rank;}#endregion

2.2、Union 操作

<1> 原始方案
首先我们会对集合的所有元素进行打散,最后每个元素都是一个独根的树,然后我们 Union 其中某两个元素,让他们成为一个集合,最坏情况下我们进行 M 次的 Union 时会存在这样的一个链表的场景。
image.png
从图中我们可以看到,Union 时出现了最坏的情况,而且这种情况还是比较容易出现的,最终导致在 Find 的时候就相当复杂了,为 O(N)。
<2> 按秩合并
我们发现出现这种情况的原因在于我们 Union 时都是将合并后的大树作为小树的孩子节点存在,那么我们在 Union 时能不能判断一下,将小树作为大树的孩子节点存在,最终也就降低了新树的深度,比如图中的 Union(D,{E,F})的时候可以做出如下修改。
image.png
可以看出,我们有效的降低了树的深度,在 N 个元素的集合中,构建树的深度不会超过 LogN 层。M 次操作的复杂度为 O(MlogN),从代码上来说,我们用 Rank 来统计树的秩,可以理解为树的高度,独根树时 Rank=0,当两棵树的 Rank 相同时,可以随意挑选合并,在新根中的 Rank++ 就可以了。

 #region 合并两个不相交集合/// <summary>/// 合并两个不相交集合/// </summary>/// <param name="root1"></param>/// <param name="root2"></param>/// <returns></returns>public void Union(char root1, char root2){char x1 = Find(root1);char y1 = Find(root2);//如果根节点相同则说明是同一个集合if (x1 == y1)return;//说明左集合的深度 < 右集合if (dic[x1].rank < dic[y1].rank){//将左集合指向右集合dic[x1].parent = y1;}else{//如果 秩 相等,则将 y1 并入到 x1 中,并将x1++if (dic[x1].rank == dic[y1].rank)dic[x1].rank++;dic[y1].parent = x1;}}#endregion

2.3、Find 操作

我们学算法,都希望能把一个问题优化到不能优化的地步,针对 logN 的级别,我们还能优化吗?当然可以。
<1> 路径压缩
在 Union 和 Find 这两种操作中,显然我们在 Union 上面已经做到了极致,下面我们在 Find 上面考虑一下,是不是可以在 Find 上运用伸展树的思想,这种伸展思想就是压缩路径。
image.png
从图中我们可以看出,当我 Find(F)的时候,找到“F”后,我们开始一直回溯,在回溯的过程中给,把该节点的父亲指向根节点。最终我们会形成一个压缩后的树,当我们再次 Find(F)的时候,只要 O(1)的时间就可以获取,这里有个注意的地方就是 Rank,当我们在路径压缩时,最后树的高度可能会降低,可能你会意识到原先的 Rank 就需要修改了,所以我要说的就是,当路径压缩时,Rank 保存的就是树高度的上界,而不仅仅是明确的树高度,可以理解成"伸缩椅"伸时候的长度。

 #region  查找x所属的集合/// <summary>/// 查找x所属的集合/// </summary>/// <param name="x"></param>/// <returns></returns>public char Find(char x){//如果相等,则说明已经到根节点了,返回根节点元素if (dic[x].parent == x)return x;//路径压缩(回溯的时候赋值,最终的值就是上面返回的"x",也就是一条路径上全部被修改了)return dic[x].parent = Find(dic[x].parent);}#endregion

我们注意到,在路径压缩后,我们将 LogN 的复杂度降低到 Alpha(N),Alpha(N)可以理解成一个比 hash 函数还有小的常量,这就是算法的魅力。
image.png

相关文章:

基于C#实现并查集

一、场景 有时候我们会遇到这样的场景&#xff0c;比如:M{1,4,6,8},N{2,4,5,7}&#xff0c;我的需求就是判断{1,2}是否属于同一个集合&#xff0c;当然实现方法有很多&#xff0c;一般情况下&#xff0c;普通青年会做出 O(MN)的复杂度&#xff0c;那么有没有更轻量级的复杂度呢…...

opencv-图像轮廓

轮廓可以简单认为成将连续的点&#xff08;连着边界&#xff09;连在一起的曲线&#xff0c;具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。 • 为了更加准确&#xff0c;要使用二值化图像。在寻找轮廓之前&#xff0c;要进行阈值化处理或者 Canny 边界检…...

小黑子—Maven高级

Maven高级篇 二 小黑子的Maven高级篇学习1. 分模块开发1.1 分模块开发设计1.2 分模块开发实现1.2.1 抽取domain层1.2.2 抽取dao层 2. 依赖管理2.1 依赖传递2.2 可选依赖2.3 排除依赖 3. 继承与聚合3.1 聚合3.2 继承3.3 总结 4. 属性4.1 配置文件加载属性4.2 版本管理 5. 多环境…...

一个正整数转为2进制和8进制,1的个数相同的第23个数是什么?

package cn.com;import java.lang.*;//默认加载public class C2 {//10进制转8进制static int HtoO(int n){int cnt 0;while(n!0){cntn%8;n/8;}return cnt;}//10进制转2进制static int HtoB(int n){int cnt 0;while(n!0){cntn%2;n/2;}return cnt;}public static void main(Str…...

Unity阻止射线穿透UI的方法之一

if(UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()) return; 作者&#xff1a;StormerZ https://www.bilibili.com/read/cv27797873/ 出处&#xff1a;bilibili...

HarmonyOS开发:ArkTs常见数据类型

前言 无论是Android还是iOS开发&#xff0c;都提供了多种数据类型用于常见的业务开发&#xff0c;但在ArkTs中&#xff0c;数据类型就大有不同&#xff0c;比如int&#xff0c;float&#xff0c;double&#xff0c;long统一就是number类型&#xff0c;当然了也不存在char类型&…...

Unsupervised MVS论文笔记

Unsupervised MVS论文笔记 摘要1 引言2 相关工作3 实现方法3.1 网络架构3.2 通过光度一致性学习3.3 MVS的鲁棒光度一致性3.4 学习设置和实施的细节3.5.预测每幅图像的深度图 4 实验4.1 在DTU上的结果4.2 消融实验 Tejas Khot and Shubham Agrawal and Shubham Tulsiani and Chr…...

Matplotlib图形注释_Python数据分析与可视化

Matplotlib图形注释 添加注释文字、坐标变换 有的时候单单使用图形无法完整清晰的表达我们的信息&#xff0c;我们还需要进行文字进行注释&#xff0c;所以matplotlib提供了文字、箭头等注释可以突出图形中重点信息。 添加注释 为了使我们的可视化图形让人更加容易理解&#…...

如何把A3 pdf 文章打印成A4

1. 用Adobe Acrobat 打开pdf 2 打印 选择海报 进行调整即可如下图,见下面红色的部分。...

【Vue】vue指令

目录 V-html v-show和v-if v-show 显示 隐藏 v-if 显示 隐藏 总结 显示隐藏的应用场景 未登录的情况 登录的情况 v- else 和 v-else-if v-if 和v-else v-if 和 v-else-if 总结&#xff1a; v-on 语法一&#xff1a; 语法二&#xff1a; 调用传参 v-bind…...

记录华为云服务器(Linux 可视化 宝塔面板)-- 安全组篇

文章目录 前言安全组说明安全组的特性安全组的应用场景 进入安全组添加基本规则添加自定义规则如有启发&#xff0c;可点赞收藏哟~ 前言 和windows防火墙类似&#xff0c;安全组是一种虚拟防火墙&#xff0c;具备状态检测和数据包过滤功能&#xff0c;可以对进出云服务器的流量…...

基于Python 中创建 Sentinel-2 RGB 合成图像

一、前言 下面的python代码将带您了解如何从原始 Sentinel-2 图像创建 RGB 合成图像的过程。 免费注册后&#xff0c;可以从 Open Access Hub 下载原始图像。 请注意&#xff0c;激活您的帐户可能需要 24 小时&#xff01; 二、准备工作 &#xff08;1&#xff09;导入必要的库…...

保姆级连接FusionInsight MRS kerberos Hive

数新网络&#xff0c;让每个人享受数据的价值https://xie.infoq.cn/link?targethttps%3A%2F%2Fwww.datacyber.com%2F 概述 本文将介绍在华为云 FusionInsight MRS&#xff08;Managed Relational Service&#xff09;的Kerberos环境中&#xff0c;如何使用Java和DBeaver实现远…...

electerm 跨平台的终端 /ssh/sftp 客户端

文章目录 electerm功能特性主题配色 electerm 每个程序员基本都离开SSH链接工具,目前市场上好用的基本都是收费的 给大家推荐一款国人开发的开源链接工具https://github.com/electerm/electerm 到目前为止star已经9.5K了,非常受欢迎 功能特性 支持ssh,telnet,serialport,本地和…...

Anthropic LLM论文阅读笔记

研究时间&#xff1a;与Instrcut GPT同期的工作&#xff0c;虽然其比ChatGPT发布更晚&#xff0c;但是其实完成的时间比ChatGPT更早。与ChatGPT的应用区别&#xff1a;该模型比ChatGPT回答我不知道的概率更高。将强化学习用于大语言模型&#xff08;RLHF&#xff09;&#xff1…...

docker启动容器失败,然后查看日志,docker logs查看容器出现报错:

docker 启动容器失败&#xff0c;然后docker logs 查看容器出现报错&#xff1a; error from daemon in stream: Error grabbing logs: invalid character l after object key:value pair在网上看到的 解决方案&#xff1a; 找到你日志文件目录&#xff1a; docker inspect …...

【开源】基于Vue.js的网上药店系统

项目编号&#xff1a; S 062 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S062&#xff0c;文末获取源码。} 项目编号&#xff1a;S062&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 药品类型模块2.3 药…...

App 设计工具

目录 说明 打开 App 设计工具 示例 创建 App 创建自定义 UI 组件 打开现有 App 文件 打包和共享 App 本文主要讲述以交互方式创建 App。 说明 App 设计工具是一个交互式开发环境&#xff0c;用于设计 App 布局并对其行为进行编程。 可以使用 App 设计工具&#xff1a…...

毅速:3D打印随形透气钢为解决模具困气提供了新助力

在模具行业中&#xff0c;困气是一个较常见的问题。解决困气问题的方法有很多&#xff0c;透气钢就是其一。传统的制造的透气钢往往存在一些不足&#xff0c;如加工难度大、无法满足复杂形状的需求等。随着3D打印技术的发展&#xff0c;一种新型的随形透气钢技术逐渐崭露头角&a…...

某软件商店app抓包分析与sign加密算法实现

文章目录 1. 写在前面2. 抓包配置3. 抓包分析4. 接口测试5. sign加密算法6. 数据效果展示 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...