查看原文
其他

腾讯终面:求两个文件中的QQ交集

脚本之家 2022-05-10

The following article is from 爱码有道 Author 点击关注👉👉

 关注
脚本之家
”,与百万开发者在一起

出处:爱码有道(ID:aimayoudao)

如若转载请联系原公众号

今天,我们来看一道腾讯的终面题目,能否做对这道题,在很大程度上决定了能否拿到腾讯的offer,来看看:

A文件有30亿个QQ号码,B文件有40亿个QQ号码,求A文件和B文件中QQ号码的交集,内存大小限制为1GB.


一. 直接暴力比较

最简单的方法是直接暴力比较,如下:




显然,这种方法要比较的次数是:30亿*40亿,时间复杂度太大了,无法通过腾讯面试


二. 利用hashmap

既然时间复杂度不符合要求,那就要反思一下暴力比较的算法了,显然,应该用哈希表,优化查找速度,如下:




显然,时间复杂度大大降低,只需要遍历上面一层即可。然而,空间的占用还是太大了,1GB的内存根本无法容纳40亿个QQ号。


三. 分治切割文件

既然内存容纳不下,那就想办法进行切割吧,比如:根据QQ号码的最后一位的值来切割A文件和B文件,使文件变小。显然,尾数为jQQ号码只可能在Aj文件和Bj文件中,只需要比较Aj和Bj文件即可。

QQ号最后一位
A文件的切割
B文件的切割
0
A0
B0
1
A1
B1
2
A2
B2
3
A3B3
...
...
...


通过切割的方法,可以化大为小,让内存容纳得下,对应的图示如下:


需要强调的是,仅仅以QQ号最后一位来划分,那么每个小文件的数据量大约是原来文件的1/10, 可能还是偏大,怎么办?

可以考虑以QQ号的最后3位来划分,那么每个小文件的数据量大约是原来大文件的1/1000,甚至还可以更细地来进行划分。

通过一定的规则进行分割,把A文件和B文件中同类型数据划分到对应的小文件中,解决了内存问题,能勉强通过腾讯面试


四. 利用bitmap

我们回头看一下,要么是时间不符合要求,要么是空间不符合要求,那有没有时间和空间都符合要求的数据结构呢?

显然有的!我们可以对hashmap进行优化,采用bitmap这种数据结构,可以顺利地同时解决时间问题和空间问题。

在很多实际项目中,bitmap经常用到。我看了不少组件的源码,发现很多地方都有bitmap实现,bitmap图解如下:


这是一个unsigned char类型,可以看到,共有8位,取值范围是[0, 255],如上这个unsigned char的值是255,它能标识0~7这些数字都存在。

同理,如下这个unsigned char类型的值是254,它对应的含义是:1~7这些数字存在,而数字0不存在:


由此可见,一个unsigned char类型的数据,可以标识0~7这8个整数的存在与否。以此类推:

  • 一个unsigned int类型数据可以标识0~31这32个整数的存在与否。

  • 两个unsigned int类型数据可以标识0~63这64个整数的存在与否。


显然,可以推导出来:512MB大小足够标识所有QQ号码的存在与否,请注意:QQ号码的理论最大值为2^32 - 1,大概是43亿左右。接下来的问题就很简单了:

用512MB的unsigned int数组来记录B文件中QQ号码的存在与否,形成一个bitmap. 然后遍历A文件中的QQ, 看是否在bitmap中,如果在,那么该QQ号码就同时存在于A和B两个文件中。

bitmap非常巧妙,这种方式能通过腾讯的面试。当时我在腾讯终面时时遇到了这个题目,先简要指明了为什么1和2方法不行,然后给出了3和4中的方法,并说明了3和4的优缺点,万事大吉。

bitmap很重要,也是经常涉及到的考点,不能不掌握。我们也会一步一个脚印,争取每篇文章讲清讲透一件事,也希望大家阅读后有所收获,心情愉快。

  推荐阅读:

美团面试:请手写一个快排,被我怼了!

逻辑面试题:叫你戴帽子

算法面试题:草坪修整

算法面试题:放苹果

面试题:孔融找梨(看似不难,其实不易)

每日打卡赢积分兑换书籍入口

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存