1. 程式人生 > 其它 >JavaScript 資料結構與演算法--並查集的封裝-leetCode

JavaScript 資料結構與演算法--並查集的封裝-leetCode

技術標籤:資料結構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;