并查集通常用来求解有几个联通集的问题;
leecode上相关的题目有:
leetcode959-由斜杠划分区域
leetcode684-冗余链接
leetcode721-账户合并
leetcode1202-交换字符串中的元素
leetcode1319-联通网络的操作次数
leetcode947-移除最多的同行或同列石头
初步接触并查集不太好理解,其实并查集就是寻找节点的代表元
先明确几个概念
1.集合树:所有节点以代表节点为父节点构成的多叉树
2.节点的代表节点:可以理解为节点的父节点,从当前节点出发,可以向上找到的第一个节点
3.集合的代表节点:可以理解为根节点,意味着该集合内所有节点向上走,最终都能到达的节点 来个图帮助理解
上图中是一棵集合树,树中有1-6总计6个节点,整个集合的代表节点是1,4节点的代表节点是3,6节点的代表节点是1,无论沿着哪个节点向上走,最终都会达到集合代表节点的1节点。
创建并查集,首先需要初始化数组parent,表示节点的代表结点(注意不是集合的代表节点);初始的时候,每个节点的代表结点是自身节点;通过合并,我们需要不断的更新这个parent。
以上参考:通俗讲解并查集,帮助小白快速理解(里边讲解更加详细过程)
如果有一组节点需要合并,通过parent进行合并之后,寻找集合的代表节点数n(由下边封装的find函数来实现),即有n个集合,也就有n个联通集。
以下是用JS实现简单的并查集代码
class UnionFind {
constructor (n) {//n是节点数
this.parent = new Array(n).fill(0).map((element, index) => index); //初始化并查集
}
union (index1, index2) {
this.parent[this.find(index2)] = this.find(index1); // 将两节点代表元 的上一级代表节点进行合并
}
//
find (index) {
if (this.parent[index] !== index) {
this.parent[index] = this.find(this.parent[index]);
}
return this.parent[index];
}
}
创建并查集,并返回联通集合的数目,合并操作根据实际情况操作
let uf = new UnionFind(node); //实参node是节点数
/** 此处进行合并uf.union(x,y)操作 **/
const root = new Set(); //
for(let i=0 ; i<node ; i++){
if(!root.has(uf.find(i))){
root.add(uf.find(i));
}
}
return root.size;