求解“微信群覆盖”的三种方法:暴力,染色,链表,并查集(文章没火,你有责任)...

本文深入探讨了解决微信群覆盖问题的四种方法:暴力法、染色法、链表法和并查集法。文章从面试题出发,详细解释每种方法的思路、实现步骤和优化技巧,重点讨论了如何通过数据结构和算法优化来提高效率。最后,强调了解决复杂问题时的思考过程和迭代优化的重要性。
摘要由CSDN通过智能技术生成

这是一篇聊算法的文章,从一个小面试题开始,扩展到一系列基础算法,包含几个部分:

(1) 题目简介;

(2) 思路一:暴力法;

(3) 思路二:染色法;

(4) 思路三:链表法;

(5) 思路四:并查集法;

除了聊方案,重点分享思考过程。文章较长,可提前收藏。

第一部分:题目简介

问题提出:求微信群覆盖

微信有很多群,现进行如下抽象:

(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) 不断的进行上述操作,直到剩下所有的微信群都不含相同的用户为止;

将上述操作称:求群的覆盖。

设计算法,求群的覆盖,并说明算法时间与空间复杂度。

画外音:你遇到过类似的面试题吗?

对于一个复杂的问题,思路肯定是“先解决,再优化”,大部分人不是神,很难一步到位。先用一种比较“笨”的方法解决,再看“笨方法”有什么痛点,优化各个痛点,不断升级方案。

第二部分:暴力法

拿到这个问题,很容易想到的思路是:

(1) 先初始化M个集合,用集合来表示微信群gid与用户uid的关系;

(2) 找到哪两个(哪些)集合需要合并;

(3) 接着,进行集合的合并;

(4) 迭代步骤二和步骤三,直至所有集合都没有相同元素,算法结束;

第一步,如何初始化集合?

set这种数据结构,大家用得很多,来表示集合:

(1) 新建M个set来表示M个微信群gid;

(2) 每个set插入N个元素来表示微信群中的用户uid;

set有两种最常见的实现方式,一种是树型set,一种是哈希型set

假设有集合:

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

树型set的实现如下:

98bc9c9cfe8fb73538df0d8e36a5ae33.png

其特点是:

(1) 插入和查找的平均时间复杂度是O(lg(n));

(2) 能实现有序查找;

(3) 省空间;

哈希型set实现如下:

505820d3935014356cfd9cf5c693bc91.png

其特点是:

(1) 插入和查找的平均时间复杂度是O(1);

(2) 不能实现有序查找;

画外音:求群覆盖,哈希型实现的初始化更快,复杂度是O(M*N)。

第二步,如何判断两个(多个)集合要不要合并?

集合对set(i)和set(j),判断里面有没有重复元素,如果有,就需要合并,判重的伪代码是:

// 对set(i)和set(j)进行元素判断并合并

(1)    foreach (element in set(i))

(2)    if (element i

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值