並查集是一種樹形結構,它是由並查集演算法進行維護的。而並查集演算法(union-find-algorithm),顧名思義,它主要是由 「合併集合」 和 「查詢集合」,」合併集合「是將兩個連通的集合合併為乙個集合,」查詢集合「判斷某個節點的代表節點,也就是根節點。
圖的連通狀態如上圖所示,共分為三個集合,灰色、藍色、粉色。在乙個集合中任何兩個點都是連通的。
如何判斷兩個點是否在同一集合中呢,我們可以組織一種樹形結構,選擇乙個點當做根節點。要判斷兩個點是否在同一集合中,只需要分別對兩個點向上尋找,一直找到根節點。如果根節點相同,那麼連個點在同一集合中,兩個點是連通的。
不同集合之間一定不能連通。
並查集演算法是由乙個陣列和兩個函式構成,陣列 parents[ ] 其實就是樹形結構的儲存,記錄了每個點的前導點是什麼。函式 find 是查詢, union 是合併。
3.1 查詢演算法
int len =
1000
;int pre[len]
;int
find
(int c)
int i = c, j;
while
(i != r)
return r;
}
查詢過程如圖所示:
3.2 合併演算法
void
union
(int node1,
int node2)
}
3.3 路徑壓縮
這裡的壓縮演算法是為了提高查詢效率,直接令每乙個節點的父節點為根節點,那麼每次要查詢的時候只需要一次訪問即可找到根節點。
130. 被圍繞的區域
難度中等208
給定乙個二維的矩陣,包含'x'
和'o'
(字母 o)。
找到所有被'x'
圍繞的區域,並將這些區域裡所有的'o'
用'x'
填充。
示例:
x x x x
x o o x
x x o x
x o x x
執行你的函式後,矩陣變為:
x x x x
x x x x
x x x x
x o x x
解釋:被圍繞的區間不會存在於邊界上,換句話說,任何邊界上的'o'
都不會被填充為'x'
。 任何不在邊界上,或不與邊界上的'o'
相連的'o'
最終都會被填充為'x'
。如果兩個元素在水平或垂直方向相鄰,則稱它們是「相連」的。
並查集:
class
unionfind
}public
void
union
(int node1,
int node2)
}public
intfind
(int node)
return node;
}boolean
isconnect
(int node1,
int node2)
}
將邊界的 o 和 內部的 o 分成兩個集合,然後對內部的 o 進行替換為 xx
public
class
solution
else
if(j-
1>=
0&& board[i]
[j-1]==
'o')
if(i +
1<= rows -
1&& board[i+1]
[j]==
'o')
if(j+
1<= cols -
1&& board[i]
[j+1]==
'o')}}
}}for(
int i =
0; i < rows; i++)}
}}public
intgetindex
(int i,
int j)
}
並查集理解
作用 連通分量的查詢與合併 理解 1.將連通分量看成乙個集合,該集合包含了連通分量的所有點。連同方式無關緊要,只有屬於和不屬於與這個集合的區別。2.每個集合都可看成一棵樹,這個集合的標誌 這棵樹的標誌 就是這棵樹的根。3.如果把節點x的父親節點儲存在pre x 中,那麼再從pre x 找它的父親節點...
並查集理解
學了這麼久的資料結構了,還是有好些演算法並沒弄清楚,搞得有些筆試題都是沒有思路,今天就講講並查集。感覺這東西吧,就是分圈子,乙個人自成乙個圈子,若分屬於兩個不同圈子的人在某時刻成了好朋友,那這兩個圈子就合併成了乙個圈子,最終在題目中形成多個圈子進行分析。判斷兩個人是不是乙個圈子要不停的找朋友驗證,這...
並查集的理解
並查集的模板,不理解也要背下來 include 萬能標頭檔案 using namespace std int par 100000 ran 10000 個數與深度 int n,m void init int n 初始化 當不需要返回值的時候,函式的型別標void。其實這個也是會返回乙個值,好像是呼叫...