染色法求解「微信羣覆蓋」,沒收穫你錘我!

題目:求微信羣覆蓋

微信有不少羣,現進行以下抽象:
(1) 每一個微信羣由一個惟一的gid標識;
(2) 微信羣內每一個用戶由一個惟一的uid標識;
(3) 一個用戶能夠加入多個羣;
(4) 羣能夠抽象成一個由不重複uid組成的集合,例如:
g1{u1, u2, u3}
g2{u1, u4, u5}
能夠看到,用戶u1加入了g1與g2兩個羣。
畫外音,注意:
gid和uid都是uint64;
集合內沒有重複元素;面試

假設微信有M個羣(M爲億級別),每一個羣內平均有N個用戶(N爲十級別).算法

如今要進行以下操做:
(1) 若是兩個微信羣中有相同的用戶,則將兩個微信羣合併,並生成一個新微信羣;
例如,上面的g1和g2就會合併成新的羣:
g3{u1, u2, u3, u4, u5};
畫外音:集合g1中包含u1,集合g2中包含u1,合併後的微信羣g3也只包含一個u1。
(2) 不斷的進行上述操做,直到剩下全部的微信羣都不含相同的用戶爲止;
將上述操做稱:求羣的覆蓋。微信

設計算法,求羣的覆蓋,並說明算法時間與空間複雜度。
畫外音:58同城2013年校招筆試題。架構

前文《暴力法求解「微信羣覆蓋」》,經過如下四個步驟,實施了求解:
(1) 先初始化M個集合,用集合來表示微信羣gid與用戶uid的關係;
(2) 找到哪兩個集合須要合併;
(3) 對有重複元素的集合,進行集合合併;
(4) 迭代步驟二和步驟三,遍歷全部集合對,有相同元素的持續合併,直到算法結束;ide

但總的來講,暴力法效率很是低,《暴力法求解「微信羣覆蓋」》同時提出了幾個優化方向,今天重點討論第一個優化方向:能不能一次合併多個集合?優化

暴力法中,判斷兩個集合set<i>和set<j>是否須要合併,思路是:遍歷set<i>中的全部element,看在set<j>中是否存在,若是存在,說明存在交集,則須要合併。ui

哪些集合可以一次性合併?

當某些集合中包含同一個元素時,能夠一次性合併。設計

怎麼一次性發現,哪些集合包含同一個元素,併合並去重呢?

回顧一下工做中的相似需求:
M個文件,每一個文件包含N個用戶名,或者N個手機號,如何合併去重?
最多見的玩法是:
cat file_1 file_2 … file_M | sort | uniq > result3d

這裏的思路是什麼?
(1) 把M*N個用戶名/手機號輸出;
(2) sort排序,排序以後相同的元素會相鄰;
(3) uniq去重,相鄰元素若是相同只保留一個;blog

「排序以後相同的元素會相鄰」,就是一次性找出全部可合併集合的關鍵,這是染色法的核心。

舉一個栗子:
假設有6個微信羣,每一個微信羣有若干個用戶:
s1={1,0,5} s2={3,1} s3={2,9}
s4={4,6} s5={4,7} s6={1,8}
假設使用樹形set來表示集合。
染色法求解「微信羣覆蓋」,沒收穫你錘我!
首先,給同一個集合中的全部元素染上相同的顏色,表示來自同一個集合。
染色法求解「微信羣覆蓋」,沒收穫你錘我!
而後,對全部的元素進行排序,會發現:

  • 相同的元素必定相鄰,而且必定來自不一樣的集合
  • 同一個顏色的元素被打散了

染色法求解「微信羣覆蓋」,沒收穫你錘我!
這些相鄰且相同的元素,來自哪個集合,這些集合就是須要合併的,如上圖:

  • 粉色的1來自集合s1,紫色的1來自集合s2,黃色的1來自集合s6,因此s1s2s6須要合併
  • 藍色的4來自集合s4,青色的4來自集合s5,因此s4s5須要合併

不用像暴力法遍歷全部的集合對,而是一個排序動做,就能找到全部須要合併的集合。
畫外音:暴力法一次處理2個集合,染色法一次能夠合併N個集合。
染色法求解「微信羣覆蓋」,沒收穫你錘我!

集合合併的過程,能夠想象爲,相同相鄰元素所在集合,染成第一個元素的顏色:

  • 紫色和黃色,染成粉色
  • 青色,染成藍色

最終,剩餘三種顏色,也就是三個集合:
s1={0,1,3,5,8}
s3={2,9}
s4={4,6,7}

神奇不神奇!!!

染色法有意思麼?但仍有兩個遺留問題:
(1) 粉色1,紫色1,黃色1,三個元素如何找到這三個元素所在的集合s1s2s6呢?
(2) s1s2s6三個集合如何快速合併?
畫外音:假設總元素個數n=MN,若是使用樹形set,合併的複雜度爲O(nlg(n)),即O(MNlg(M*N))。

或許有朋友會問,怎麼來排序?
《拜託,面試別再問我基數排序了!》
《拜託,面試別再問我計數排序了!》
《拜託,面試別再問我桶排序了!》
以前介紹了三種,時間複雜度是線性的排序算法。本例中,基數排序和桶排序都是很是不錯的選擇。

仍是那句話,思路比結論更重要,進一步的優化,且聽下回分解。
染色法求解「微信羣覆蓋」,沒收穫你錘我!

架構師之路-分享可落地的技術文章

相關推薦:《暴力法求解「微信羣覆蓋」》

相關文章
相關標籤/搜索