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

2023-11-30 14:58

本文主要是介绍染色法求解“微信群覆盖”,没收获你锤我!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:求微信群覆盖

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

(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) 迭代步骤二和步骤三,遍历所有集合对,有相同元素的持续合并,直到算法结束;

 

但总的来说,暴力法效率非常低,《暴力法求解“微信群覆盖”》同时提出了几个优化方向,今天重点讨论第一个优化方向:能不能一次合并多个集合?

 

暴力法中,判断两个集合set<i>和set<j>是否需要合并,思路是:遍历set<i>中的所有element,看在set<j>中是否存在,如果存在,说明存在交集,则需要合并。

 

哪些集合能够一次性合并?

当某些集合中包含同一个元素时,可以一次性合并。

 

怎么一次性发现,哪些集合包含同一个元素,并合并去重呢?

回顾一下工作中的类似需求:

M个文件,每个文件包含N个用户名,或者N个手机号,如何合并去重?

最常见的玩法是:

cat file_1 file_2 … file_M | sort | uniq > result

 

这里的思路是什么?

(1) 把M*N个用户名/手机号输出;

(2) sort排序,排序之后相同的元素会相邻

(3) uniq去重,相邻元素如果相同只保留一个;

 

“排序之后相同的元素会相邻”,就是一次性找出所有可合并集合的关键,这是染色法的核心。

 

举一个栗子

假设有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=M*N,如果使用树形set,合并的复杂度为O(n*lg(n)),即O(M*N*lg(M*N))。

 

或许有朋友会问,怎么来排序?

《拜托,面试别再问我基数排序了!》

《拜托,面试别再问我计数排序了!》

《拜托,面试别再问我桶排序了!》

之前介绍了三种,时间复杂度是线性的排序算法。本例中,基数排序桶排序都是非常不错的选择。

 

还是那句话,思路比结论更重要,进一步的优化,且听下回分解。

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

相关推荐:

《暴力法求解“微信群覆盖”》

这篇关于染色法求解“微信群覆盖”,没收获你锤我!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437464

相关文章

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.

最大流=最小割=最小点权覆盖集=sum-最大点权独立集

二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。 在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。   二分图最小点权覆盖     从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。 建模:     原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t

POJ3041 最小顶点覆盖

N*N的矩阵,有些格子有物体,每次消除一行或一列,最少要几次消灭完。 行i - >列j 连边,表示(i,j)处有物体,即 边表示 物体。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;impo

STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂 一、需求分析 高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生 管理员:给学生和实验室教师创建账号并分发 实验室教师:审核学生的预约申请 学生:申请使用实验室 高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验

2024 年高教社杯全国大学生数学建模竞赛题目——2024 年高教社杯全国大学生数学建模竞赛题目的求解

2024 年高教社杯全国大学生数学建模竞赛题目 (请先阅读“ 全国大学生数学建模竞赛论文格式规范 ”) 2024 年高教社杯全国大学生数学建模竞赛题目 随着城市化进程的加快、机动车的快速普及, 以及人们活动范围的不断扩大,城市道 路交通拥堵问题日渐严重,即使在一些非中心城市,道路交通拥堵问题也成为影响地方经 济发展和百姓幸福感的一个“痛点”,是相关部门的棘手难题之一。 考虑一个拥有知名景区

Minimal coverage -uva 覆盖线段,贪心

一道经典的贪心问题,具体方法就是将(an,bn)区间,按照an从小到大的顺序进行排序,之后从0开始, 取最大的有效区间,这里用到了结构体的快排,否则可能会超时. #include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 100000 + 10#define BOTTOM -50000 - 10str

基于SA模拟退火算法的多车辆TSP问题求解matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述        基于SA模拟退火算法的多车辆TSP问题求解matlab仿真,三个车辆分别搜索其对应的最短路径,仿真后得到路线规划图和SA收敛曲线。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 (完整程序运行后无水印)

过滤器:覆盖过滤器如何在凝结水处理系统中应用

本文介绍了覆盖过滤器的基本原理,阐述了覆盖过滤器处理凝结水中悬浮物和胶体的工艺流程及铺膜、过滤、爆膜等环节的操作规范。指出覆盖过滤器在运行中存在铺不上膜、铺膜不匀、脱膜等常见的故障并提出处理方法。   0·引言   凝结水处理系统设置覆盖过滤器的目的是除去凝结水中的金属腐蚀物及油类等杂质。这些杂质通常为悬浮颗粒和胶体,如果不被滤除,会污染离子交换树脂,反冲洗过滤器原理使其交换量下降,工作周