Java算法 数据结构基础 并查集 模版 [洛谷-P3367]

目录

题目地址

题目描述

输入输出样例

并查集模版

介绍

1. 路径压缩(Path Compression)

2. 按秩合并(Union by Rank / Size)

代码讲解

操作讲解

时间复杂度分析

应用场景


题目地址

【模板】并查集 - 洛谷

题目描述

输入输出样例

并查集模版

class UnionFind {
    private int[] parent; // 存储每个元素的父节点
    private int[] size;   // 存储每个集合的大小,用于按秩合并

    // 初始化并查集
    public UnionFind(int n) {
        parent = new int[n + 1]; // 因为编号从 1 到 N,所以数组大小是 N+1
        size = new int[n + 1];   // 存储每个集合的大小
        for (int i = 1; i <= n; i++) {
            parent[i] = i;  // 每个元素的父节点初始为自己
            size[i] = 1;    // 每个元素的初始大小为 1
        }
    }

    // 查找元素 x 所在的集合,带路径压缩优化
    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);  // 路径压缩:将父节点直接指向根节点
        }
        return parent[x];  // 返回根节点(集合的代表)
    }

    // 合并两个集合,带按秩合并优化
    public void union(int x, int y) {
        int rootX = find(x);  // 查找 x 的根节点
        int rootY = find(y);  // 查找 y 的根节点

        if (rootX != rootY) {  // 如果根节点不同,说明它们不在同一个集合
            // 按秩合并:较小的集合合并到较大的集合
            if (size[rootX] < size[rootY]) {
                parent[rootX] = rootY;
                size[rootY] += size[rootX];  // 更新根节点的大小
            } else {
                parent[rootY] = rootX;
                size[rootX] += size[rootY];  // 更新根节点的大小
            }
        }
    }

    // 判断 x 和 y 是否在同一个集合中
    public boolean connected(int x, int y) {
        return find(x) == find(y);  // 如果两个元素的根节点相同,说明在同一个集合中
    }
}

介绍

并查集(Union-Find)是一种数据结构,主要用于处理一些不交集的合并及查询问题,特别是在图论中用来解决连通性问题。并查集支持两种基本操作:

  1. 查找(Find):判断某个元素属于哪个集合,返回该集合的代表元素(根)。
  2. 合并(Union):将两个集合合并成一个集合。

并查集通过 路径压缩按秩合并 来优化效率,减少操作的时间复杂度。

1. 路径压缩(Path Compression)

路径压缩是一种优化查找操作的方法。在查找过程中,我们不仅仅返回当前元素的根节点,还将当前节点的父节点直接指向根节点,这样可以加速以后的查找操作。也就是说,当你调用 find(x) 时,你将 x 的祖先节点都直接连接到根节点。

2. 按秩合并(Union by Rank / Size)

按秩合并是一种优化合并操作的方法,旨在确保树的深度(或大小)尽可能小。在合并两个集合时,较小的集合(树)会被合并到较大的集合(树)上。这样,最终形成的树的深度会较小,从而提高查找操作的效率。

代码讲解

java


复制代码
class UnionFind {
    private int[] parent; // 存储每个元素的父节点
    private int[] size;   // 存储每个集合的大小,用于按秩合并

    // 初始化并查集
    public UnionFind(int n) {
        parent = new int[n + 1]; // 因为编号从 1 到 N,所以数组大小是 N+1
        size = new int[n + 1];   // 存储每个集合的大小
        for (int i = 1; i <= n; i++) {
            parent[i] = i;  // 每个元素的父节点初始为自己
            size[i] = 1;    // 每个元素的初始大小为 1
        }
    }

    // 查找元素 x 所在的集合,带路径压缩优化
    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);  // 路径压缩:将父节点直接指向根节点
        }
        return parent[x];  // 返回根节点(集合的代表)
    }

    // 合并两个集合,带按秩合并优化
    public void union(int x, int y) {
        int rootX = find(x);  // 查找 x 的根节点
        int rootY = find(y);  // 查找 y 的根节点

        if (rootX != rootY) {  // 如果根节点不同,说明它们不在同一个集合
            // 按秩合并:较小的集合合并到较大的集合
            if (size[rootX] < size[rootY]) {
                parent[rootX] = rootY;
                size[rootY] += size[rootX];  // 更新根节点的大小
            } else {
                parent[rootY] = rootX;
                size[rootX] += size[rootY];  // 更新根节点的大小
            }
        }
    }

    // 判断 x 和 y 是否在同一个集合中
    public boolean connected(int x, int y) {
        return find(x) == find(y);  // 如果两个元素的根节点相同,说明在同一个集合中
    }
}

操作讲解

  1. 初始化
    • 我们首先创建一个大小为 n + 1parent 数组和 size 数组,parent[i] 存储的是元素 i 的父节点,size[i] 存储的是以 i 为根节点的集合大小。初始化时,每个元素的父节点是它自己,且每个集合的大小为 1。
  1. 查找(Find)操作
    • 查找操作会递归地找元素的父节点,直到找到根节点(即 parent[i] == i)。为了提高查找效率,我们在递归过程中使用路径压缩,将沿途的所有节点的父节点直接指向根节点。
  1. 合并(Union)操作
    • 合并两个集合时,首先找到它们的根节点。如果根节点不同,说明它们属于不同的集合,可以将一个集合合并到另一个集合。为了减少树的深度,我们使用按秩合并的策略,将较小的树合并到较大的树上。
  1. 判断是否连接(Connected)
    • 如果两个元素的根节点相同,说明它们属于同一个集合;如果根节点不同,则说明它们属于不同的集合。

时间复杂度分析

  • 查找操作:由于路径压缩优化,查找操作的时间复杂度接近常数,实际是 O(α(n)),其中 α(n)阿克曼函数的反函数,增长速度非常缓慢,接近常数。
  • 合并操作:合并操作的时间复杂度也是 O(α(n))

因此,并查集的所有操作几乎都可以视为常数时间复杂度 O(α(n))

应用场景

  • 图的连通性问题:例如判断图中的两个节点是否连通。
  • 动态连通性问题:在动态变化的图中,需要不断地进行节点的合并和查询。
  • 集合合并问题:如并购合并、社交网络中的好友关系等。

并查集通过路径压缩和按秩合并的优化,能在大规模数据中高效处理集合合并与查询问题,是非常高效的算法之一。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/954702.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PyCharm文档管理

背景&#xff1a;使用PyCharmgit做文档管理 需求&#xff1a;需要PyCharm自动识别docx/xslx/vsdx等文件类型&#xff0c;并在PyCharm内点击文档时唤起系统内关联应用(如word、excel、visio) 设置步骤&#xff1a; 1、file -》 settings -》file types 2、在Files opened i…

卷积神经05-GAN对抗神经网络

卷积神经05-GAN对抗神经网络 使用Python3.9CUDA11.8Pytorch实现一个CNN优化版的对抗神经网络 简单的GAN图片生成 CNN优化后的图片生成 优化模型代码对比 0-核心逻辑脉络 1&#xff09;Anacanda使用CUDAPytorch2&#xff09;使用本地MNIST进行手写图片训练3&#xff09;…

基于springboot的租房网站系统

作者&#xff1a;学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等 文末获取“源码数据库万字文档PPT”&#xff0c;支持远程部署调试、运行安装。 项目包含&#xff1a; 完整源码数据库功能演示视频万字文档PPT 项目编码&#xff1…

创建 WordPress 插件(第一部分):添加管理页面

WordPress 是互联网上最受欢迎的内容管理系统之一。它是用 PHP 创建的&#xff0c;可以处理从博客到商业网站的一切需求。事实上&#xff0c;我们的博客和网站都使用 WordPress。在本文中&#xff0c;我将向你展示如何创建一个 WordPress 插件&#xff0c;该插件会在管理员控制…

「港科技」联手「地平线」打造GPT风格的自动驾驶世界模型:DrivingWorld

摘要 最近在自回归&#xff08;AR&#xff09;生成模型方面的成功&#xff0c;例如自然语言处理中的GPT系列&#xff0c;激发了在视觉任务中复制这一成功的努力。一些研究尝试将这种方法扩展到自动驾驶中&#xff0c;通过构建基于视频的世界模型来生成逼真的未来视频序列和预测…

FPGA工程师成长四阶段

朋友&#xff0c;你有入行三年、五年、十年的职业规划吗&#xff1f;你知道你所做的岗位未来该如何成长吗&#xff1f; FPGA行业的发展近几年是蓬勃发展&#xff0c;有越来越多的人才想要或已经踏进了FPGA行业的大门。很多同学在入行FPGA之前&#xff0c;都会抱着满腹对职业发…

SOME/IP协议详解 基础解读 涵盖SOME/IP协议解析 SOME/IP通讯机制 协议特点 错误处理机制

车载以太网协议栈总共可划分为五层&#xff0c;分别为物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0c;传输层&#xff0c;应用层&#xff0c;其中今天所要介绍的内容SOME/IP就是一种应用层协议。 SOME/IP协议内容按照AUTOSAR中的描述&#xff0c;我们可以更进一步…

为ARM64架构移植Ubuntu20.04换源的发现

在为ARM64架构(RK3566)移植ubuntu20.04的时候发现在更换为国内源之后&#xff0c;无法正常完成apt update,报错为: Ign:25 http://mirrors.aliyun.com/ubuntu focal-updates/main arm64 Packages …

Playwright vs Selenium:全面对比分析

在现代软件开发中&#xff0c;自动化测试工具在保证应用质量和加快开发周期方面发挥着至关重要的作用。Selenium 作为自动化测试领域的老牌工具&#xff0c;长期以来被广泛使用。而近年来&#xff0c;Playwright 作为新兴工具迅速崛起&#xff0c;吸引了众多开发者的关注。那么…

【全套】基于机器学习的印度森林火灾发生概率的分析与预测

【私信送源码文档】基于机器学习的印度森林火灾发生概率的分析与预测 对应的ppt 摘 要 随着全球气候变化的不断加剧&#xff0c;火灾的频发和规模逐渐增大&#xff0c;成为备受关注的问题。本文旨在提高对火灾发生概率的准确性&#xff0c;为火灾的预防和管理提供科学支持。在…

【Go】Go Gin框架初识(一)

1. 什么是Gin框架 Gin框架&#xff1a;是一个由 Golang 语言开发的 web 框架&#xff0c;能够极大提高开发 web 应用的效率&#xff01; 1.1 什么是web框架 web框架体系图&#xff08;前后端不分离&#xff09;如下图所示&#xff1a; 从上图中我们可以发现一个Web框架最重要…

TCP/IP协议簇及封装与解封装

TCP/IP协议簇 现如今用的参考模型TCP/IP 是一个协议簇&#xff0c;它组建了整个互联网 最主要的是TCP/IP 和这两个协议&#xff0c;所以起名为TCP/IP TCP/IP模型 TCP/IP标准模型——四层 TCP/IP对等模型——五层 数据链路层分为两个子层&#xff1a; LLC子层&#xff1a;逻辑…

《基于卷积神经网络的星图弱小目标检测》论文精读

Dim small target detection based on convolutinal neural network in star image 摘要 由于低信噪比目标和复杂背景&#xff0c;星图中弱小目标的检测是一项具有挑战性的任务。本文提出了一种深度学习方法&#xff0c;用于在背景不均匀和不同类型的噪声下检测单帧星图中的弱…

如何选择Ubuntu版本

一、为什么要选择Ubuntu系统&#xff1f; CentOS官方已全面停止维护CentOS Linux项目 。具体来说&#xff0c;CentOS 8已于2021年12月31日停止维护&#xff0c;而CentOS 7则在2024年6月30日结束了生命周期 。这意味着这些版本不再接收官方的安全更新、bug修复或技术支持 二、…

计算机视觉算法实战——视频分析(Video Analysis)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​​​​ ​​​​​​​​​​​​ ​​​​​ 视频分析是计算机视觉中的一个重要领域&#xff0c;旨在从视频数据中提取有用的信息&…

O2O同城系统架构与功能分析

2015工作至今&#xff0c;10年资深全栈工程师&#xff0c;CTO&#xff0c;擅长带团队、攻克各种技术难题、研发各类软件产品&#xff0c;我的代码态度&#xff1a;代码虐我千百遍&#xff0c;我待代码如初恋&#xff0c;我的工作态度&#xff1a;极致&#xff0c;责任&#xff…

讲一下ZooKeeper的持久化机制?

大家好&#xff0c;我是锋哥。今天分享关于【讲一下ZooKeeper的持久化机制&#xff1f;】面试题。希望对大家有帮助&#xff1b; 讲一下ZooKeeper的持久化机制&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 ZooKeeper 是一个开源的分布式协调服务&…

C++ 文字识别OCR

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

数据库(MySQL)练习

数据库&#xff08;MySQL&#xff09;练习 一、练习1.15练习1.16练习 二、注意事项2.1 第四天 一、练习 1.15练习 win11安装配置MySQL超详细教程: https://baijiahao.baidu.com/s?id1786910666566008458&wfrspider&forpc 准备工作&#xff1a; mysql -uroot -p #以…

【HTML+CSS+JS+VUE】web前端教程-35-字体图标

优点: 轻量性:加载速度快,减少http请求 灵活性:可以利用CSS设置大小颜色等 兼容性:网页字体支持所有现代浏览器,包括IE低版本 使用字体图标: 1、注册账户并登录 2、选取图标或搜索图标 3、添加购物车 4、下载代码 5、选择font-class引用 iconfont Logo:https://www.ic…