我们来聊一道常见的考题,也出现在腾讯面试的三面环节,非常有意思。具体的题目如下:

文件中有40亿个QQ号码,请设计算法对QQ号码去重,相同的QQ号码仅保留一个,内存限制1G.

这个题目的意思应该很清楚了,比较直白。为了便于大家理解,我来画个动图玩玩,希望大家喜欢。

能否做对这道题目,很大程度上就决定了能否拿下腾讯的offer,有一定的技巧性,一起来看下吧。

在原题中,实际有40亿个QQ号码,为了方便起见,在图解和叙述时,仅以4个QQ为例来说明。

方法一:排序

很自然地,最简单的方式是对所有的QQ号码进行排序,重复的QQ号码必然相邻,保留第一个,去掉后面重复的就行。

原始的QQ号为:

排序后的QQ号为:

去重就简单了:

可是,面试官要问你,去重一定要排序吗?显然,排序的时间复杂度太高了,无法通过腾讯面试。

方法二:hashmap

既然直接排序的时间复杂度太高,那就用hashmap吧,具体思路是把QQ号码记录到hashmap中:

mapFlag[123] = true
mapFlag[567] = true
mapFlag[123] = true
mapFlag[890] = true

由于hashmap的去重性质,可知实际自动变成了:

mapFlag[123] = true
mapFlag[567] = true
mapFlag[890] = true

很显然,只有123,567,890存在,所以这也就是去重后的结果。

可是,面试官又要问你了:实际要存40亿QQ号码,1G的内存够分配这么多空间吗?显然不行,无法通过腾讯面试。

方法三:文件切割

显然,这是海量数据问题。看过很多面经的求职者,自然想到文件切割的方式,避免内存过大。

可是,绞尽脑汁思考,要么使用文件间的归并排序,要么使用桶排序,反正最终是能排序的。

既然排序好了,那就能实现去重了,貌似就万事大吉了。我只能坦白地说,高兴得有点早哦。

接着,面试官又要问你:这么多的文件操作,效率自然不高啊。显然,无法通过腾讯面试。

方法四: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数组来记录文件中QQ号码的存在与否,形成一个bitmap,比如:

bitmapFlag[123] = 1
bitmapFlag[567] = 1
bitmapFlag[123] = 1
bitmapFlag[890] = 1

实际上就是:

bitmapFlag[123] = 1
bitmapFlag[567] = 1
bitmapFlag[890] = 1

然后从小到大遍历所有正整数(4字节),当bitmapFlag值为1时,就表明该数是存在的。

而且,从上面的过程可以看到,自动实现了去重。显然,这种方式可以通过腾讯的面试。

扩展练习一

文件中有40亿个互不相同的QQ号码,请设计算法对QQ号码进行排序,内存限制1G.

很显然,直接用bitmap, 标记这40亿个QQ号码的存在性,然后从小到大遍历正整数,当bitmapFlag的值为1时,就输出该值,输出后的正整数序列就是排序后的结果。

请注意,这里必须限制40亿个QQ号码互不相同。通过bitmap记录,客观上就自动完成了排序功能。

扩展练习二

文件中有40亿个互不相同的QQ号码,求这些QQ号码的中位数,内存限制1G.

我知道,一些刷题经验丰富的人,最开始想到的肯定是用堆或者文件切割,这明显是犯了本本主义错误。直接用bitmap排序,当场搞定中位数。

扩展练习三

文件中有40亿个互不相同的QQ号码,求这些QQ号码的top-K,内存限制1G.

我知道,很多人背诵过top-K问题,信心满满,想到用小顶堆或者文件切割,这明显又是犯了本本主义错误。直接用bitmap排序,当场搞定top-K问题。

扩展练习四

文件中有80亿个QQ号码,试判断其中是否存在相同的QQ号码,内存限制1G.

我知道,一些吸取了经验教训的人肯定说,直接bitmap啊。然而,又一次错了。根据容斥原理可知:

因为QQ号码的个数是43亿左右(理论值2^32 - 1),所以80亿个QQ号码必然存在相同的QQ号码。

海量数据的问题,要具体问题具体分析,不要眉毛胡子一把抓。有些人完全不刷题,肯定不行。有些人刷题后不加思考,不会变通,也是不行的。好了,先说这么多。我们也会一步一个脚印,争取每篇文章讲清讲透一件事,也希望大家阅读后有所收获,心情愉快。

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

腾讯三面:40亿个QQ号码如何去重?相关推荐

  1. 腾讯三面:40 亿个 QQ 号码如何去重?

    今天,我们来聊一道常见的考题,也出现在腾讯面试的三面环节,非常有意思.具体的题目如下: 文件中有40亿个QQ号码,请设计算法对QQ号码去重,相同的QQ号码仅保留一个,内存限制1G. 这个题目的意思应该 ...

  2. 利用bitmap处理海量数据问题:43亿QQ号所占内存大小为什么是512M?40亿个QQ号如何去重?

    ​参考: 腾讯43亿QQ号码用完后怎么办? 腾讯三面:40亿个QQ号码如何去重 一.背景: 首先,明确两点: QQ号是 unsigned int 类型(4字节无符号整数,共32bit), 也就是说 Q ...

  3. 腾讯太狠:40亿QQ号, 给你1G内存,怎么去重?

    说在前面 在40岁老架构师 尼恩的读者社区(50+)中,最近有小伙伴拿到了一线互联网企业如腾讯.美团.阿里.拼多多.极兔.有赞.希音的面试资格,遇到一几个很重要的面试题: 40亿Q号如何设计算法去重, ...

  4. 40亿个QQ号,限制1G内存,如何去重?【已通过代码实现】

    前几天发现一个有趣的文章 "40亿个QQ号,限制1G内存,如何去重?",发现很有意思,就想着用代码实现一下,下面是分析和实现过程 一.审题分析 一个 QQ 号现在最长有 11 位, ...

  5. 40亿个QQ号,限制1G内存,如何去重?

    40亿个unsigned int,如果直接用内存存储的话,需要: 4*4000000000 /1024/1024/1024 = 14.9G ,考虑到其中有一些重复的话,那1G的空间也基本上是不够用的. ...

  6. 采用位图存储40亿条qq号,用来记录登录状态

    假设有需要你在一个8G内存的容器里面做个服务,用来根据用户输入的qq号,判断此qq号是否登录过.qq总数有40亿,每天的登录记录了有1000亿条,每个qq号存储占4byte,设计下用哪种数据结构? 1 ...

  7. 腾讯不敢发放的一个QQ号码

    大家先去查找60481729这个QQ......怎么样?什么也查不到吧! 为什么极其普通的一个号TX一直不敢放出来呢? 首先得从这个号码的数字上分析原因.大家注意没?我把60481729这个QQ从中间 ...

  8. 腾讯终面:孤单的QQ号码怎么找?

  9. 10亿个QQ号码,找出重复次数最多的那一个

    hash取模,将号码分散在多个小文件里存储,然后分别对文件内号码排序,统计出现次数最多的那一个,最后对所有最多值取最大的那一个,为所求.

最新文章

  1. AI找Bug,一键快速预测
  2. 实战:使用Nginx限流
  3. 轻松实现基于Heartbeat的高可用web服务集群
  4. c 语言程序设计阚道宏,C语言用宏实现静态多态
  5. python字典下标是什么_python列表、元组、字典
  6. 常见危险文件列表 以及清除方法
  7. c语言不规则窗口,C语言不规则数组和指针
  8. linux之怎么使vim永久显示行号
  9. SSM整合简单登录案例
  10. python3类的继承详解_python3 多重继承机制
  11. ActiveMQ下载与安装(Linux环境下进行)
  12. BPSK、8PSK、QPSK、16QAM、64QAM区别与联系
  13. Codejock Suite Pro 19.3.0 Carck版本
  14. STM32应用笔记分类汇总,值得收藏
  15. tftp命令使用说明
  16. 李想的理想,不太「理想」
  17. linux开机自动执行脚本、运行程序
  18. AUGNLG: Few-shot Natural Language Generation using Self-trained Data Augmentation翻译
  19. 更加简洁易用——wangEditor富文本编辑器新版本发布
  20. vs2017 error1071:在注释中遇到意外的文件结束

热门文章

  1. 土是独体字结构吗_205砂浆、混凝土强度等级与定额不同时,你会调整换算吗?...
  2. eol python_乱记 EOL(End of Line)在windows和linux不同导致的Python问题
  3. php tea 算法 源码,PHP教程:TEA算法实现
  4. 学习java前_学习java之前
  5. IPv4和IPv6有什么异同?
  6. C++中的深拷贝和浅拷贝(详解)
  7. 06. 从尾到头打印链表
  8. EnvironmentError: mysql_config not found
  9. golang 指针总结(与C/C++区别不大,就是不可以p+1偏移)
  10. A-Graph Games_2019牛客暑期多校训练营(第三场)