并查集 ——(快速判断两个元素是否在同一个集合中)

news2024/12/26 0:14:48

五、并查集

0、并查集概念

并查集(Union-Find)是一种用于维护元素分组信息的数据结构。它支持以下两种基本操作:

  1. 合并(Union):将两个不同的集合合并为一个集合。
  2. 查找(Find):确定某个元素属于哪个集合。

并查集通常用于解决涉及集合合并和查询的问题,例如:

  • 连通性问题:判断两个元素是否在同一个连通分量中。
  • 图的连通性问题:判断一个无向图是否连通。
  • 基于并查集的最小生成树算法,如Kruskal算法。

并查集的实现主要有两种:
1、基于数组的并查集:使用一个数组来表示集合,数组中的每个元素代表该元素所属的集合的代表元素。
2、基于树的并查集:使用树结构来表示集合,每个集合用一棵树表示,树的根节点就是该集合的代表元素。

image.png

1、模拟实现并查集

import java.util.Arrays;

public class UnionFindSet {
    public int[] elem;

    public UnionFindSet(int n) {
        this.elem = new int[n];
        Arrays.fill(elem,-1);
    }

    /**
     * 查找数据x 的根节点
     * @param x
     * @return 下标
     */
    public int findRoot(int x) {
        if(x < 0) {
            throw new IndexOutOfBoundsException("下标不合法,是负数");
        }
        while (elem[x] >= 0 ) {
            x = elem[x];//1  0
        }
        return x;
    }

    /**
     * 查询x1 和 x2 是不是同一个集合
     * @param x1
     * @param x2
     * @return
     */
    public boolean isSameUnionFindSet(int x1,int x2) {
        int index1 = findRoot(x1);
        int index2 = findRoot(x2);
        if(index1 == index2) {
            return true;
        }
        return false;
    }

    /**
     * 这是合并操作
     * @param x1
     * @param x2
     */
    public void union(int x1,int x2) {
        int index1 = findRoot(x1);
        int index2 = findRoot(x2);
        if(index1 == index2) {
            return;
        }
        elem[index1] = elem[index1] + elem[index2];
        elem[index2] = index1;
    }

    public int getCount() {
        int count = 0;
        for (int x : elem) {
            if(x <  0) {
                count++;
            }
        }
        return count;
    }

    public void print() {
        for (int x : elem) {
            System.out.print(x+" ");
        }
        System.out.println();
    }

    //省份的数量
    public int findCircleNum(int[][] isConnected) {
        int n = isConnected.length;
        UnionFindSet ufs = new UnionFindSet(n);
        for(int i = 0;i < isConnected.length;i++) {
            for(int j = 0;j < isConnected[i].length;j++) {
                if(isConnected[i][j] == 1) {
                    ufs.union(i,j);
                }
            }
        }
        return ufs.getCount();
    }

    //等式的满足性
    public boolean equationsPossible(String[] equations) {
        UnionFindSet ufs = new UnionFindSet(26);
        for(int i = 0; i < equations.length;i++) {
            if(equations[i].charAt(1) == '=') {
                ufs.union(equations[i].charAt(0)-'a',equations[i].charAt(3)-'a');
            }
        }
        for(int i = 0; i < equations.length;i++) {
            if(equations[i].charAt(1) == '!') {
                int index1 = ufs.findRoot(equations[i].charAt(0)-'a');
                int index2 = ufs.findRoot(equations[i].charAt(3)-'a');
                if(index1 == index2) {
                    return false;
                }
            }
        }
        return true;
    }

    public static void main(String[] args) {
        String[] str = {"a==b","b!=a"};
        //equationsPossible(str);
    }

    //亲戚题
    public static void main2(String[] args) {
        int n = 10;
        int m = 3;
        int p = 2;

        UnionFindSet unionFindSet = new UnionFindSet(n);

        System.out.println("合并:0和6:");
        unionFindSet.union(0,6);
        unionFindSet.union(0,1);
        System.out.println("合并:3和7:");
        unionFindSet.union(3,7);
        System.out.println("合并:4和8:");
        unionFindSet.union(4,8);

        System.out.println("以下是不是亲戚:");
        boolean flg = unionFindSet.isSameUnionFindSet(1,8);
        if(flg) {
            System.out.println("是亲戚!");
        }else {
            System.out.println("不是亲戚!");
        }
        System.out.println("当亲的亲戚关系 "+unionFindSet.getCount()+" 对!");
    }

    public static void main1(String[] args) {
        UnionFindSet unionFindSet = new UnionFindSet(10);
        System.out.println("合并:0和6:");
        unionFindSet.union(0,6);
        System.out.println("合并:0和7:");
        unionFindSet.union(0,7);
        System.out.println("合并:0和8:");
        unionFindSet.union(0,8);

        System.out.println("合并:1和4:");
        unionFindSet.union(1,4);
        System.out.println("合并:1和9:");
        unionFindSet.union(1,9);
        System.out.println("合并:2和3:");
        unionFindSet.union(2,3);

        System.out.println("合并:2和5:");
        unionFindSet.union(2,5);

        unionFindSet.print();

        System.out.println("合并:8和1:");
        unionFindSet.union(8,1);

        unionFindSet.print();

        System.out.println("查找是不是同一个集合");
        System.out.println(unionFindSet.isSameUnionFindSet(6, 9));
        System.out.println(unionFindSet.isSameUnionFindSet(8, 2));

    }
}

2、并查集主要功能

image.png

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++题解】1168. 歌唱比赛评分

问题&#xff1a;1168. 歌唱比赛评分 类型&#xff1a;数组找数 题目描述&#xff1a; 四&#xff08;1&#xff09; 班要举行一次歌唱比赛&#xff0c;以选拔更好的苗子参加校的歌唱比赛。评分办法如下&#xff1a;设 N 个评委&#xff0c;打 N 个分数&#xff08; 0≤每个分…

PointCloudLib MLS算法法线估计 C++版本

测试效果 简介 MLS(Moving Least Squares,移动最小二乘法)算法在法线估计中的应用是一种基于局部数据拟合的技术,它通过对点云中每个点的邻域数据进行多项式拟合来估计该点的法线。以下是MLS算法在法线估计中的详细解释: MLS算法的基本原理 MLS算法是一种无网格的曲线和…

生物素-吡啶-叠氮的组成成分与特性

一、基本信息 中文名称&#xff1a;生物素-吡啶-叠氮 英文名称&#xff1a;Biotin Picolyl Azide CAS号&#xff1a;可能因不同供应商或产品而有所不同&#xff0c;但通常会有一个特定的CAS号与之对应。 分子量&#xff1a;根据产品的具体规格&#xff0c;分子量可能有所不同&a…

六西格玛培训:控制图——洞察过程真相的利器

在追求卓越绩效与持续质量改进的征途中&#xff0c;六西格玛无疑是企业不可或缺的导航灯。作为一套严谨而系统的管理方法&#xff0c;六西格玛不仅帮助企业识别并减少过程中的变异与缺陷&#xff0c;还促进了流程的优化与创新。而在这套强大的方法论中&#xff0c;控制图作为核…

创建通用JS公共模块并发布至npm

title: 创建通用JS公共模块并发布至npm tags: UMD rollup verdaccio npm categories: 模块化 概要内容 创建&#xff1a;JS公共模块 打包&#xff1a;使用rollup 打包公共模块 发布&#xff1a;js公共模块至verdaccio平台 发布&#xff1a;js公共模块至npm平台 如何创建JS公共模…

如何开发一个大模型应用

随着人工智能技术的快速发展&#xff0c;大模型应用已成为许多领域的核心竞争力。大模型应用通常指的是基于大规模数据集训练得到的深度学习模型&#xff0c;具有强大的特征表示能力和泛化性能。本文将详细介绍如何开发一个大模型应用&#xff0c;包括模型设计、数据准备、训练…

Synergy键鼠跨屏幕同步

小记 Synergy 在多台计算机之间使用单个键盘和鼠标&#xff0c;使用一台计算机的键盘、鼠标或触控板来控制附近的计算机&#xff0c;并在它们之间无缝工作 支持Windows Mac Linux 和树莓派&#xff0c;解放桌面空间&#xff0c;减少操作复杂性&#xff0c;多屏操作神器没错了 …

PostgreSQL 中如何处理数据的并发插入和唯一约束的冲突解决?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何处理数据的并发插入和唯一约束的冲突解决一、并发插入和唯一约束的基本概念&#xf…

对于GPT-5在一年半后发布的期待!

首先&#xff0c;如果GPT-5真如OpenAI首席技术官米拉穆拉蒂&#xff08;Mira Murati&#xff09;在采访中所透露的那样&#xff0c;在一年半后发布&#xff0c;并在某些领域达到博士级的智能&#xff0c;这无疑将是一个令人振奋的消息。这一预测不仅反映了AI技术的快速发展&…

PostgreSQL 中如何处理数据的并发读写和事务隔离级别选择?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何处理数据的并发读写和事务隔离级别选择一、并发读写的挑战&#xff08;一&#xff0…

SpringBoot之健康监控(Actuator)

1&#xff0c;基本介绍 Spring Actuator 是 Spring Boot 提供的一个扩展模块&#xff0c;用于监控和管理应用程序的生产环境。它通过 HTTP 端点暴露了大量的监控和管理功能&#xff0c;使得开发者可以在运行时查看应用程序的运行状况、配置信息、性能指标等。 主要功能&#…

重生奇迹mu游戏中的防御成功率

在重生奇迹游戏中&#xff0c;玩家通常除了追求高防御能力外&#xff0c;还会关注一种特殊属性——防御成功率。防御成功率的提高可以帮助玩家闪避攻击&#xff0c;并展现出无敌的效果&#xff0c;因此是防御技能的关键表现之一。 在游戏中&#xff0c;角色的防御成功率和敏捷属…

Zymo试剂盒产品目录,你了解过吗?

在加利福尼亚州奥兰治市的一个小车库里诞生&#xff0c;到今天的行业领导者&#xff0c;Zymo Research 的愿景是在生物医学领域产生积极影响&#xff0c;并为人类的更大福祉做出贡献。这一愿景涉及 Zymo Research的各个方面&#xff0c;并自 1994 年以来一直指导着公司的发展、…

Java | Leetcode Java题解之第231题2的幂

题目&#xff1a; 题解&#xff1a; class Solution {static final int BIG 1 << 30;public boolean isPowerOfTwo(int n) {return n > 0 && BIG % n 0;} }

高校节能环保建设

全球能源危机和环境保护问题日益严重。我国高等院校数量多&#xff0c;在校师生人数多。高等院校作为能耗消耗主体及其在校师生作为节能环保理念的重要传播群体&#xff0c;高校节能环保校园建设显得尤为重要。本文就节能环保校园建设中节能、节水和环保三个方面进行了思考&…

可视化作品集(13):智慧交通方向的这组大屏,绝对亮眼。

本期分享智慧交通方向的可视化化大屏&#xff0c;本期的视觉效果绝对亮眼。

ysoserial代码分析-反射

前言&#xff1a; ysoserial作为优秀的反序列化攻击工具&#xff0c;其提供的攻击调用链也是很简单好用&#xff0c;但是一直没有分析过其代码逻辑&#xff0c;最近有空正好分析了一下&#xff0c;对反序列化理解有更好的帮助 代码分析&#xff1a; 其代码中最重要的两个是反…

虚拟机 VMware Workstation- 安装详细步骤

目录 虚拟化概念VMware Workstation 简介一、安装准备1. 安装环境2. 软件下载 二、常见问题1. 虚拟机的【默认位置】会在C盘&#xff0c;盘符内存不够的建议改为D盘或别的盘符2. 验证许可证是否密钥是否成功。进入虚拟机点击【帮助】下的关于VMware Workstation(A)可以查看验证…

Android Stuido Gradle build编译报错原因排查

事情是这样的&#xff0c;在更新了支付宝sdk的aar文件后&#xff0c;运行项目&#xff0c;报错了。如下图&#xff1a; 但是没有给出更多错误信息。想尝试通过gradlew compileDebug --stacktrace来输出更多build时的信息&#xff0c;但没有得到更多有效信息。 接下来&#xff…

AI+ 资源数据分析运营助手

在数字化浪潮席卷全球的今天&#xff0c;资源管理&#xff0c;作为企业运营的中枢神经&#xff0c;正迎来一场由人工智能&#xff08;AI&#xff09;引领的智慧变革。从资源的智能分配到问题的瞬间解决&#xff0c;AI 正在重塑资源管理的每一个角落&#xff0c;让效率与精准成为…