并查集(union&find)

1、理论知识
  • 并查集是一种树形的数据结构,用于处理一些不交集的合并及查询问题
  • Find:确定元素属于哪一个子集。用来判断两个元素是否属于同一子集
  • Union:将两个子集合并为同一个集合
2、实现方式
  • 联合 “老大->小弟” 的关系来理解并查集
  • 一般使用名为roots的数组表示,初始化时,所有元素各成一派,即对应位置存放自己的下标
//init
int[] roots=  new int[N];
for(int i=0;i
  • 查:两个元素是否属于同一个集合---->两个元素最顶端的老大是否相同
public int find(int x){
    if(roots[x]==x){
        return roots[x];
    }
    return find[roots[x]];
}
  • 并:将两个元素所属的集合合并起来
public void union(int x,int y){
    int xparent = find[x];
    int yparent = find[y];
    roots[xparent]=yparent;
}
3、两种优化方式
  • 合并:按秩合并,合并时将深度较低的分支合并到深度较高的分支中,形成一个总体深度较低的集合,需要创建一个新的rank[ ]数组存储
//init
int[] roots=  new int[N];
int[] rank = new int [N];
for(int i=0;irank[xparent]){
        roots[yparent]=xparent;
    }
    else if(rank[xparent]
  • 查找:路径压缩(使用了路径压缩,则按秩合并的意义不大)
//递归
public int find(int x){
    if(roots[x]!=x){
        roots[x]=find[roots[x]];
    }
    return roots[x];
}

//循环 速度快
public int find(int x){
    //find
    int father=x;
    while(father!=roots[father]){
        father=roots[father];
    }
    while(x!=roots[x]){
        int tmp = roots[x];
        roots[x]=father;
        x=tmp;
    }
    return father;
}
4、leetcode题目
  • 547. 省份数量
  • 684. 冗余连接
  • 1202. 交换字符串中的元素
  • 947. 移除最多的同行或同列石头 ⭕一定要看官方题解!!!!!另外一种并查集的实现方法!!使用Map来实现
  • 721. 账户合并 (补一题,虽然不是并查集,但是应该放在一起看399. 除法求值)

一道有意思的小题目: 1128. 等价多米诺骨牌对的数量

你可能感兴趣的:(并查集(union&find))