Union-Find
题目套路
Union Find解决的最核心的问题就是集合合并以及Dynamic Connectivity, 所以题目一般都可以简化成Given a set of objects, connect two objects for a bunch of times, then ask if two objects are connected (graph里是否有环)or how many connected components are there? 这里我们需要确定的前提是connect表示的是undirected, or two directional 当用union-find 解决graph的问题时,我们要把图里的每个node理解为object,然后每个edge 相当于做了一次union operation。
Union-Find模板
class UnionFind {
HashMap<Integer, Integer> roots;
int count;
public UnionFind() {
this.count = 0;
this.roots = new HashMap<Integer, Integer>();
}
// add
public void add(int num) {
count++;
roots.put(num, num);
}
// union
public void union(int num1, int num2) {
int root1 = root(num1);
int root2 = root(num2);
if (root1 == root2) {
return;
}
roots.put(root1, root2);
count--;
}
// find
public boolean find(int num1, int num2) {
return root(num1) == root(num2);
}
// root
public int root(int num) {
int temp = num;
while (roots.get(num) != num) {
num = roots.get(num);
}
int root = num;
num = temp;
while (roots.get(num) != num) {
int parent = roots.get(num);
roots.put(num, root);
num = parent;
}
return root;
}
}
这里注意我们每次在考虑edge的find和union之前都要确保node已经add进去了。比如graph valid tree和find number of connected components in undirected graph这两道题,我们都要先把所有的node都add进去。因为题目只给了edges信息。而像number of islands 2这道题,我们只给了node信息,我们自然而然就先把node加进去,但是这时要check edge是否valid。
抽象化:寻找联通量
会在哪些情况下要求找connected components
在graph里面找connected components是关于graph的一个常见问题。具体可以用一个 矩阵来表示。
undirected weak in directed strong in directed
BFS yes no no
DFS yes no no
Union-Find yes yes no
所以可以看见,如果是无向图,那么这时候BFS/DFS都可以用,而且代码量比union-find 简单,所以杀鸡不用宰牛刀。但是如果是有向图求connected components,那么只有union-find可以求 weak connected components,而如果是strong connected components,都不可以。
还有一点,如果graph是变化的,比如总是有新的node连接起来(集合合并),那么哪怕是无向图,BFS/DFS 的time complexity也太高。这时一定要用union-find。所以对应到number of islands 2, matrix本质上是无向图,但是不断有集合合并,所以这时一定要用union-find。而number of islands 1,本质上就是在无向图里面求connected components,因为矩阵就是无向图, 而无向图每个node都可能是BFS的起点(seed),所以我们要遍历每一个点。所以总结下来, 所有的求connected components的问题都可以归为graph上的问题。
题目
- Leetcode 323. Number of Connected Components in an Undirected Graph
- Leetcode 261. Graph Valid Tree
- Leetcode 305. Number of Islands II