并查集 --- Java通用模版

什么是并查集

并查集可以解决什么问题:判断两个节点是否在一个集合,也可以将两个节点添加到一个集合中。

并查集常用于处理大规模数据下的元素分组问题,特别是在数据量极大时,使用正常的数据结构可能会导致空间或时间复杂度过高。并查集通过其高效的数据处理能力,能够在有限的时间内完成元素的合并和查询操作,特别适用于竞赛编程和实际工程应用中。

leetcode题目: 冗余连接 冗余连接 II 省份数量 最长连续序列 统计无向图中无法互相达到的点数

并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题
-些常见的用途有求连通子图、求最小生成树的Kruskal 算法和求最近公共祖先(LCA)等。

基本原理:每个集合用一个树来表示,树的 root 的代表整个集合,每个节点存储它的父节点,parent[x] 表示 x 的父节点。

并查集通常包含两种操作:

  1. 初始化
    每个节点的父节点指向自己
    在这里插入图片描述
  2. 查询 find
    如果两个节点是连通的,那么他们一定拥有相同的根节点
    在这里插入图片描述

通用模版

public class Solution {
    //记录连通分量个数
    private int count;
    //节点x的根节点是parent[x]
    private int[] parent;
    // 记录树的“重量”
    private int[] size;

    public Solution(int n){
        //一开始互不相通 连通分量等于n
        this.count = n;
        //一开始,每个节点是自己的父节点
        parent = new int[n];
        size = new int[n];
        for (int i = 0; i < n ; i++) {
            parent[i] = i;
            size[i] = 1;
        }
    }

    /**
     * 将p和q连接, 如果两个节点被连通,那么则让其中的一个根节点连接到另一个节点的根节点上
    */
    public void union(int p,int q){
        int rootP = find(p);
        int rootQ = find(q);
        if(rootP == rootQ){
            return;
        }
        
        //将两颗树合并为一颗,小树接到大树下面,较平衡     
        if (size[rootP] > size[rootQ]) {
            parent[rootQ] = rootP;
            size[rootP] += size[rootQ];
        } else {
            parent[rootP] = rootQ;
            size[rootQ] += size[rootP];
        }
        //两个分量合二为一
        count--;
    }

    /**
    * 返回某个节点x的根节点
    */
    private int find(int x){
        //根节点的parent[x] == x
        while (parent[x] != x){
            parent[x] = parent[parent[x]];
            x = parent[x];
        }
        return x;
    }

    /**
     * 判断p和q是否连通:如果两个节点是连通的,那么他们一定拥有相同的根节点
     */
    public boolean connected(int p,int q){
        int rootP = find(p);
        int rootQ = find(q);
        return rootP == rootQ;
    }

    /**
    * 返回具体有多少个连通分量
     */
    public int count(){
        return count;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值