JavaScript 資料結構與演算法--並查集的封裝-leetCode
阿新 • • 發佈:2021-01-27
技術標籤:資料結構leetcodejavascript資料結構
並查集通常用來求解有幾個聯通集的問題;
leecode上相關的題目有:
leetcode959-由斜槓劃分區域
leetcode684-冗餘連結
leetcode721-賬戶合併
leetcode1202-交換字串中的元素
leetcode1319-聯通網路的操作次數
leetcode947-移除最多的同行或同列石頭
初步接觸並查集不太好理解,其實並查集就是尋找節點的代表元
先明確幾個概念
1.集合樹:所有節點以代表節點為父節點構成的多叉樹
2.節點的代表節點:可以理解為節點的父節點,從當前節點出發,可以向上找到的第一個節點3.集合的代表節點:可以理解為根節點,意味著該集合內所有節點向上走,最終都能到達的節點 來個圖幫助理解
上圖中是一棵集合樹,樹中有1-6總計6個節點,整個集合的代表節點是1,4節點的代表節點是3,6節點的代表節點是1,無論沿著哪個節點向上走,最終都會達到集合代表節點的1節點。
建立並查集,首先需要初始化陣列parent,表示節點的代表結點(注意不是集合的代表節點);初始的時候,每個節點的代表結點是自身節點;通過合併,我們需要不斷的更新這個parent。
以上參考:通俗講解並查集,幫助小白快速理解(裡邊講解更加詳細過程)
如果有一組節點需要合併,通過parent進行合併之後,尋找集合的代表節點數n(由下邊封裝的find函式來實現),即有n個集合,也就有n個聯通集。
以下是用JS實現簡單的並查集程式碼
class UnionFind { constructor (n) {//n是節點數 this.parent = new Array(n).fill(0).map((element, index) => index); //初始化並查集 } union (index1, index2) { this.parent[this.find(index2)] = this.find(index1); // 將兩節點代表元 的上一級代表節點進行合併 } // find (index) { if (this.parent[index] !== index) { this.parent[index] = this.find(this.parent[index]); } return this.parent[index]; } }
建立並查集,並返回聯通集合的數目,合併操作根據實際情況操作
let uf = new UnionFind(node); //實參node是節點數
/** 此處進行合併uf.union(x,y)操作 **/
const root = new Set(); //
for(let i=0 ; i<node ; i++){
if(!root.has(uf.find(i))){
root.add(uf.find(i));
}
}
return root.size;