在很多筆試題目中,經常需要將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協議,就是支援物件作為引數傳遞.剛開始...