偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

題目:求微信群覆蓋

微信有很多群,現(xiàn)進(jìn)行如下抽象:

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

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

[[249955]]

畫外音,注意:

  • gid和uid都是uint64;
  • 集合內(nèi)沒有重復(fù)元素;

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

現(xiàn)在要進(jìn)行如下操作:

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

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

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

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

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

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

設(shè)計算法,求群的覆蓋,并說明算法時間與空間復(fù)雜度。

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

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

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

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

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

set這種數(shù)據(jù)結(jié)構(gòu),大家用得很多,來表示集合:

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

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

假設(shè)有集合:

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

樹型set的實現(xiàn)如下:

其特點是:

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

哈希型set實現(xiàn)如下:

其特點是:

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

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

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

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

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

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

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

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

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

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

第三步,如何合并集合?

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

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

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

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

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

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

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

第四步:迭代第二步與第三步,直至結(jié)束

對于M個集合,暴力針對所有集合對,進(jìn)行重復(fù)元素判斷并合并,用兩個for循環(huán)可以暴力解決:

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

遞歸調(diào)用,兩個for循環(huán),復(fù)雜度是O(M*M)。

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

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

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

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

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

畫外音:

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

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

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

經(jīng)典數(shù)據(jù)結(jié)構(gòu),分離集合(disjoint set),它有三類操作:

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

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

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

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

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

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

【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】

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

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2021-12-09 15:02:21

算法微信群覆蓋開發(fā)

2021-04-20 08:30:23

微信微信輸入法張小龍

2021-04-26 05:39:03

微信輸入法騰訊

2017-03-27 13:20:36

2013-08-08 10:13:25

微信

2025-04-17 09:00:00

架構(gòu)聊消息微信

2019-12-16 17:25:04

Python微信群同步直播

2019-10-14 11:26:05

開源技術(shù) 軟件

2015-10-19 15:20:14

有魚

2020-03-17 15:01:19

微信醫(yī)保電子憑證

2021-04-27 13:43:42

微信iOS輸入法

2019-11-26 10:08:00

微信醫(yī)院掛號

2019-12-20 09:22:12

垃圾分類微信城市服務(wù)

2020-01-08 06:40:12

微信微信群移動應(yīng)用

2020-02-05 13:15:03

微信移動應(yīng)用

2020-07-27 15:06:14

微信張小龍焦慮

2021-09-30 05:39:05

微信Android 8.0騰訊

2013-10-24 11:00:30

馬云微信

2017-01-11 17:01:20

飛魚星

2015-02-13 10:20:15

微信
點贊
收藏

51CTO技術(shù)棧公眾號