染色法求解“微信群覆盖”,没收获你锤我!

题目:求微信群覆盖

微信有不少群,现进行以下抽象:
(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))。

或许有朋友会问,怎么来排序?
《拜托,面试别再问我基数排序了!》
《拜托,面试别再问我计数排序了!》
《拜托,面试别再问我桶排序了!》
以前介绍了三种,时间复杂度是线性的排序算法。本例中,基数排序和桶排序都是很是不错的选择。

仍是那句话,思路比结论更重要,进一步的优化,且听下回分解。
染色法求解“微信群覆盖”,没收获你锤我!

架构师之路-分享可落地的技术文章

相关推荐:《暴力法求解“微信群覆盖”》