非常巧妙用來解決集合問題的資料結構 並查集

2021-10-09 05:33:59 字數 1590 閱讀 6930

在很多筆試題目中,經常需要將n個不同元素劃分成不相交的集合通過一定的條件和關係讓一些集合合併。在此過程中經常需要判斷該元素是否屬於某個集合,或查詢該集合中元素的個數。適用於解決這類問題的資料結構型別稱為並查集

題目2:990. 等式方程的可滿足性

通過陣列下標標識元素本身,陣列內容標識其集合上層節點。舉個例子

在班裡有三波人是互相熟悉的,他們都有分別都有乙個老大。現在給這些人進行編號

用乙個陣列來儲存表示集合,陣列下標就是同學編號,陣列中的數字代表這個集體有多少個人。(負號後面解釋)

三個小團體分別是:team1= team2= team3=

小團隊分好夥後就變成了

從上圖可以觀察到編號3,5屬於team1,編號4,7,9屬於team2,編號6,8,10屬於team3。它們座標陣列中的值是其老大的座標。

可以得到一下結論

陣列的下標對應集合中元素的編號陣列中如果為負數,負號代表根,數字代表這個集合中的元素個數陣列中如果為非負數,代表該元素父節點在陣列中的下標。

過了一陣時間,老大0和老大1相互認識了,因此也介紹它們的小弟相互認識,因此他們也就成了同乙個集合

現在0集合就有7個人,2集合就有4個人。變成了兩個集合

通過這個例子就能了解到並查集能解決的問題。

查詢元素屬於哪個集合

根據元素陣列中資料,沿著一直查詢到資料為負數的節點。

檢視兩個元素是否屬於乙個集合

如果他們的根節點相同,他們就屬於同乙個集合

可以將兩個集合合併成乙個集合

找到兩個集合的根節點,將其中乙個根節點名稱改為另乙個根節點。

另乙個根節點加上當前集合元素個數。

集合的個數

遍歷陣列,檢視陣列元素為負數的個數,就是集合的個數。

#include

#include

using namespace std;

class unionfindset

//找到乙個元素所在根節點

intfindroot

(int index)

return index;

}//將兩個集合合併

bool union

(int set1,

int set2)

//統計集合元素

intcount()

const

return count;

}//遍歷按序輸出各集合元素

void

print()

else

if(flag ==0)

}if(i != num)

cout << endl;}}

}};

巧妙的位運算解決重複資料出現問題

題目描述 1到1000這1000個數放在含有1001個元素的陣列中,只有唯一的乙個元素值重複,其他均只出現一次,找出這個重複的值。解法1 巧妙使用位運算 public static void main string args 陣列的最後乙個元素是隨機數 就是和前面重複的那個數k 模擬這個重複的數字出...

Git 的問題解決集合

git remote rm origin 再次add就可以了 這種ssl的問題,最方便的是直接禁用 git config global http.sslverify false 不過風險這塊。學學計網再回來想想 紅色error解決 git push f 不管用就git pull rebase ori...

XFire 解決引數是物件,集合的問題

最近在看webservices xfire框架.也在網上找了點資料.基本的資料型別當引數時,很容易解決,在網上也有很多的例子.但是這樣遠遠不能滿足我們程式設計師的要求.在開發中,我們的介面經常要以物件,集合作為引數.來滿足我們的要求.而且xfire也支援soap協議,就是支援物件作為引數傳遞.剛開始...