Disjoint-set data structure 并查集
Preface
算法学习笔记(1) : 并查集: 关于684. Redundant Connection, 我之前没想明白的中国区官方题解和Neetcode答案为什么不一致,哪个更优?在看完文章后醍醐灌顶,推荐阅读。
自我理解
并查集实则就是用集合中的一个元素去代表整个元素。而用树去整理集合元素的做法不仅方便找到公共祖先,也有利于确定edge环的出现。
而我们整体的思考路径也可以看成: 你的祖先我的祖先大家不一样->合并。你的祖先我的祖先大家都一样->环的出现。
合并的路径压缩:
int find(int x)
{
if(x == fa[x])
return x;
else{
fa[x] = find(fa[x]); //父节点设为根节点
return fa[x]; //返回父节点
}
}
为什么会快,因为把每个父节点的根节点跟着更新了一遍,所以下次再寻找根节点时,则只需要往前走一步即可。根节点的x = fa[x]; 一步到位。而未更新点则会持续更新直到根节点找到。
相关例题
- 684. Redundant Connection
- 261. Graph Valid Tree
- 323. Number of Connected Components in an Undirected Graph
- 305. Number of Islands II
- 547. Number of Provinces
TimeComplexity: O(nlogn): The O(nlogn)O(n \log n)O(nlogn) time complexity arises because, without optimizations, each Find operation can take O(logn)O(\log n)O(logn) time on average, and you're performing nnn such operations. By implementing path compression and union by rank, you can optimize your algorithm to have nearly linear time complexity.
Space Complexity: O(n)