Union Find

Basics

Union/Find,并查集算法,通常用来解决动态连通性问题,即判断是否属于同一个group。 如果求具体路径,则需要用DFS来解决。

  • Initially,新建一个 length = |V| 的数组或集合,并将每个 node 指向其本身,即构建 |V| 个独立的group。每个 index 代表一个 node,其 value 为 parent node。

  • find(a, array) : 找到 array 中 a 的 root,即找到含 a 的 group 的头结点。

  • union(a, b, array) : 将 a 和 b 连接起来。首先需要找到 a 和 b 所在 group 的头结点,若不相等,则将其中一个头结点指向另一个。

优化:其实上述算法实现的是Quick-Union。Find 和 Union 的时间复杂度跟树的高度有关,即 O(Tree Height) 。降低复杂度的方法,就是减少 Tree Height,那么当我们 union 的时候,应该将“小树“连到“大树“上,以尽量避免出现 unbalanced 的情况。这就是 Weighted Quick-Union。再进一步,如果我们能把一棵树做的足够扁平化,那么时间复杂度可以更少。这里引入路径压缩,即在找根节点的同时,将节点的父节点指向爷爷节点

Path Compression

主要函数

UF(int n)

initialize N sites with integer names (0 to N - 1)

int find(int p)

group identifier for p (0 to N - 1)

void union(int p, int q)

add connection between p and q

boolean connected(int p, int q)

return true if p and q are in the same group

int count()

number of groups

基本实现

Basic Implementation of Union/Find

不同 Union/Find 算法的时间复杂度

Algorithm

Constructor

Union

Find

Quick-Find

N

N

1

Quick-Union

N

Tree height

Tree height

Weighted Quick-Union

N

lgN

lgN

Weighted Quick-Union With Path Compression

N

Very near to 1 (amortized)

Very near to 1 (amortized)

Reference

并查集(Union-Find)算法介绍 : https://blog.csdn.net/dm_vincent/article/details/7655764

经典题目

200 Number of Islands 737 Sentence Similarity II

通常情况下以 array 作为底层数据结构,但遇到 String,Character 等类型时,可以利用 HashMap 映射。

Last updated