一,概述
并查集是一種樹型的數據結構,用于處理一些不相交集合(Disjoint Sets UnionFind)的合并及查詢問題。常常在使用中以森林來表示。 進行快速規整。
二,并查集的主要操作
"人以類聚,物以群分"
(相似的在一起(合并)
查找自己屬于哪一類(查找)
兩個兩個是否是同一類)
- 1,初始化一個并查集 initUnionFind
初始化并查集,一般是將每個元素作為一個單獨的集合,對于下面的示例就是對應的元素父節點就是自己 - 2,合并兩個不相交集合 union
兩個元素,分別找到(find)他們的根節點,然后將其中一個元素的根節點的父親指向另外的一個元素的根節點 - 3,查找某個元素的根節點 find
查找一個元素的根節點,parent--->parent--->parent.....
那么問題來了,查找元素根節點途徑的元素過多,那么就有一個優化的問題-------路徑壓縮,直接將該元素的父親指向根節點或者祖先 - 4,判斷兩個元素是否屬于同一個集合 isConnected
判斷兩個元素是否屬于同一個集合,就是分別找到他們的根節點,然后判斷兩個根節點是否相等.
示例如下:
private int count;
private int[] parents;
//初始化并查集
public void initUnionFind(int m, int n, char[][] grid){
parents = new int[m*n];
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
if(grid[i][j] == '1'){
count++;
}
parents[i*n+j] = i*n+j;
}
}
}
public int find(int idx){
while(idx != parents[idx]){
//在查找的過程中壓縮路徑,減少查找的次數
parents[idx] = parents[parents[idx]];
idx = parents[idx];
}
return idx;
}
public void union(int p, int q){
int pRoot = find(p);
int qRoot = find(q);
//兩個元素的根不同,則合并
if(pRoot != qRoot){
parents[qRoot] = pRoot;
count--;
}
}
public boolean isConnected(int p, int q){
int pRoot = find(p);
int qRoot = find(q);
//兩點不連通
if(pRoot != qRoot){
return false;
}
return false;
}
三,LeetCode相關題目
128. Longest Consecutive Sequence
130. Surrounded Regions
200. Number of Islands