成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

暴力法求解“微信群覆蓋”?

開發 開發工具 前端
假設微信有M個群(M為億級別),每個群內平均有N個用戶(N為十級別),下面,我們設計算法,求群的覆蓋,并說明算法時間與空間復雜度。

題目:求微信群覆蓋

微信有很多群,現進行如下抽象:

  • 每個微信群由一個***的gid標識;
  • 微信群內每個用戶由一個***的uid標識;
  • 一個用戶可以加入多個群;
  • 群可以抽象成一個由不重復uid組成的集合,例如:
  1. g1{u1, u2, u3} 
  2. g2{u1, u4, u5} 

可以看到,用戶u1加入了g1與g2兩個群。

[[249955]]

畫外音,注意:

  • gid和uid都是uint64;
  • 集合內沒有重復元素;

假設微信有M個群(M為億級別),每個群內平均有N個用戶(N為十級別).

現在要進行如下操作:

(1) 如果兩個微信群中有相同的用戶,則將兩個微信群合并,并生成一個新微信群;

例如,上面的g1和g2就會合并成新的群:

  1. g3{u1, u2, u3, u4, u5}; 

畫外音:集合g1中包含u1,集合g2中包含u1,合并后的微信群g3也只包含一個u1。

(2) 不斷的進行上述操作,直到剩下所有的微信群都不含相同的用戶為止;

將上述操作稱:求群的覆蓋。

設計算法,求群的覆蓋,并說明算法時間與空間復雜度。

畫外音:58同城2013年校招筆試題。

對于一個復雜的問題,思路肯定是“先解決,再優化”,大部分人不是神,很難一步到位。先用一種比較“笨”的方法解決,再看“笨方法”有什么痛點,優化各個痛點,不斷升級方案。

拿到這個問題,很容易想到的思路是:

  • 先初始化M個集合,用集合來表示微信群gid與用戶uid的關系;
  • 找到哪兩個(哪些)集合需要合并;
  • 接著,進行集合的合并;
  • 迭代步驟二和步驟三,直至所有集合都沒有相同元素,算法結束;

***步,如何初始化集合?

set這種數據結構,大家用得很多,來表示集合:

  • 新建M個set來表示M個微信群gid
  • 每個set插入N個元素來表示微信群中的用戶uid

set有兩種最常見的實現方式,一種是樹型set,一種是哈希型set。

假設有集合:

  1. s={7, 2, 0, 14, 4, 12} 

樹型set的實現如下:

其特點是:

  • 插入和查找的平均時間復雜度是O(lg(n))
  • 能實現有序查找
  • 省空間

哈希型set實現如下:

其特點是:

  • 插入和查找的平均時間復雜度是O(1)
  • 不能實現有序查找

畫外音:求群覆蓋,哈希型實現的初始化更快,復雜度是O(M*N)。

第二步,如何判斷兩個(多個)集合要不要合并?

集合對set(i)和set(j),判斷里面有沒有重復元素,如果有,就需要合并,判重的偽代碼是:

  1. // 對set(i)和set(j)進行元素判斷并合并 
  2. (1)    foreach (element in set(i)) 
  3. (2)    if (element in set(j)) 
  4.          merge(set(i), set(j)); 

***行(1)遍歷***個集合set(i)中的所有元素element;

畫外音:這一步的時間復雜度是O(N)。

第二行(2)判斷element是否在第二個集合set(j)中;

畫外音:如果使用哈希型set,第二行(2)的平均時間復雜度是O(1)。

這一步的時間復雜度至少是O(N)*O(1)=O(N)。

第三步,如何合并集合?

集合對set(i)和set(j)如果需要合并,只要把一個集合中的元素插入到另一個集合中即可:

  1. // 對set(i)和set(j)進行集合合并 
  2. merge(set(i), set(j)){ 
  3. (1)    foreach (element in set(i)) 
  4. (2)    set(j).insert(element); 

***行(1)遍歷***個集合set(i)中的所有元素element;

畫外音:這一步的時間復雜度是O(N)。

第二行(2)把element插入到集合set(j)中;

畫外音:如果使用哈希型set,第二行(2)的平均時間復雜度是O(1)。

這一步的時間復雜度至少是O(N)*O(1)=O(N)。

第四步:迭代第二步與第三步,直至結束

對于M個集合,暴力針對所有集合對,進行重復元素判斷并合并,用兩個for循環可以暴力解決:

  1. (1)for(i = 1 to M) 
  2. (2)    for(ji+1 to M) 
  3.          //對set(i)和set(j)進行元素判斷并合并 
  4.          foreach (element in set(i)) 
  5.          if (element in set(j)) 
  6.          merge(set(i), set(j)); 

遞歸調用,兩個for循環,復雜度是O(M*M)。

綜上,如果這么解決群覆蓋的問題,時間復雜度至少是:

  1. O(M*N) // 集合初始化的過程 
  2. O(M*M) // 兩重for循環遞歸 
  3. O(N) // 判重 
  4. O(N) // 合并 

畫外音:實際復雜度要高于這個,隨著集合的合并,集合元素會越來越多,判重和合并的成本會越來越高。

基于“先解決,再優化”的思想,很多優化方向的問題,自然而然的從腦中蹦出:

(1) 能不能快速通過元素定位集合?

畫外音:

  • 通過集合查元素,哈希型set時間復雜度是O(1);
  • 通過元素查集合(句柄),如何來實現呢?

(2) 能不能快速進行集合合并?

(3) 能不能一次合并多個集合?

經典數據結構,分離集合(disjoint set),它有三類操作:

  • Make-set(a):生成一個只有一個元素a的集合;
  • Union(X, Y):合并兩個集合X和Y;
  • Find-set(a):查找元素a所在集合,即通過元素找集合;

特別適合用來解決這類集合合并與查找的問題,又稱為并查集。

如何利用并查集來解決求“微信群覆蓋”問題,是后文將要介紹的內容。

畫外音:先介紹“并查集”這一種方案,后續再介紹其他方案。

知道并查集的思路和原理,比知道什么是并查集更重要。

算法,其實還是挺有意思的。

【本文為51CTO專欄作者“58沈劍”原創稿件,轉載請聯系原作者】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2021-12-09 15:02:21

算法微信群覆蓋開發

2021-04-20 08:30:23

微信微信輸入法張小龍

2017-03-27 13:20:36

2021-04-26 05:39:03

微信輸入法騰訊

2013-08-08 10:13:25

微信

2019-10-14 11:26:05

開源技術 軟件

2019-12-16 17:25:04

Python微信群同步直播

2025-04-17 09:00:00

架構聊消息微信

2015-10-19 15:20:14

有魚

2020-03-17 15:01:19

微信醫保電子憑證

2021-04-27 13:43:42

微信iOS輸入法

2019-11-26 10:08:00

微信醫院掛號

2019-12-20 09:22:12

垃圾分類微信城市服務

2020-01-08 06:40:12

微信微信群移動應用

2020-02-05 13:15:03

微信移動應用

2020-07-27 15:06:14

微信張小龍焦慮

2017-01-11 17:01:20

飛魚星

2021-09-30 05:39:05

微信Android 8.0騰訊

2013-10-24 11:00:30

馬云微信

2021-05-29 07:39:07

微信微信圈子騰訊
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 狠狠插天天干 | 成人免费视频在线观看 | xx性欧美肥妇精品久久久久久 | 久久九九免费 | 中文字幕第十五页 | 99一级毛片 | 久久草在线视频 | 中文字幕亚洲在线 | 色综合视频在线 | 亚洲毛片在线观看 | 久久一区 | 成人性视频在线播放 | 欧美一级欧美三级在线观看 | 日韩精品视频在线观看一区二区三区 | 一区二区三区视频在线免费观看 | 亚洲aⅴ一区二区 | 精品免费视频一区二区 | 国产欧美精品一区二区 | 欧美一a一片一级一片 | 亚洲91精品| 亚洲精品久久国产高清情趣图文 | 日本激情视频中文字幕 | 欧美精品一区二区三区四区五区 | www.一区二区三区 | 日韩理论电影在线观看 | 国产精品一区在线 | 狠狠操狠狠操 | 亚洲精品视频久久 | 九九热精品视频在线观看 | 日韩欧美一区二区三区 | 欧美精品日韩精品国产精品 | 天天精品综合 | 日韩精品免费在线观看 | 色婷婷久久久久swag精品 | 99小视频| 日韩www| 久久久91精品国产一区二区三区 | 欧美日韩精品综合 | 亚洲精品国产a久久久久久 午夜影院网站 | 国产一区二区精品在线观看 | 精品国产欧美一区二区三区成人 |