最多連續數的子集 並查集 啟發式合併

2021-09-26 23:53:24 字數 842 閱讀 3632

題目描述:給乙個整數陣列a, 找到其中包含最多連續數的子集,比如給:15, 7, 12, 6, 14, 13, 9, 11,則返回: 5:[11, 12, 13, 14, 15]

思路:初始化每個樹子集乙個集合,預處理每個數的數值雜湊到一張表中,內容存下標,掃一次陣列,每次取找val+1以及val-1的數,如果找到了把兩者的集合合併,合併時可以按子集的大小進行啟發式合併,即小的集合合併到多的集合中,這樣能夠盡量使並查集的所有子節點都接近根位置,加快查詢效率。

code

int

find

(int x)

void

join

(int x,

int y)

else

}void

solve()

//預處理

for(

int i=

1; i<=n; i++

)int maxsize = rank[1]

, maxindex =1;

for(

int i=

2; i<=n; i++

) cout << maxsize << endl;

for(

int i=

1; i<= n; i++)if

(rank[i]

== maxsize && hash[val[i]

]== i)

cout << val[i]

<<

' ';

cout << endl;

}

並查集的啟發式合併

在原來剛接觸並查集的時候,感覺確實很方便,也是認為並查集就那麼點東西,簡單方便,但是後來無意間發現了乙個並查集的啟發式合併,可以對並查集進行優化,它優化的理論是用乙個陣列來記錄每個節點的深度,每一次合併都把節點向深度 高度 大的節點上進行合併,從而對最後的 生成樹 深度進行了優化。受益匪淺,好長時間...

並查集 啟發式合併,路徑壓縮

一直沒想過自己寫的並查集的複雜度 看那一行 還挺竊喜 貼一下正版的啟發式合併,這樣複雜度就真正到了反阿克曼函式那什麼balabala 乙個優化是 把小的樹合併到大樹中,這樣會讓深度不太大。這個優化稱為啟發式合併。乙個優化是把沿途上所有結點的父親改成根。這一步是順便的,不增加時間複雜度,卻使得今後的操...

HDU 6109 資料分割 並查集 啟發式合併

題目鏈結 略對於相等的關係很好維護,關鍵是對於不想等的關係。如果 x i 與 x j 不相等,那麼 x i 所在集合中的所有點都是和 x j 所在集合中的所有點不相等的。把不相等的 x i 與 x j 所在集合的代表結點建一條邊,如果 x i 所在集合要和其他集合合併,那麼在合併的時候指向被合併集合...