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

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

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

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

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

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

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

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

方法一:排序

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

原始的QQ号为:

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

排序后的QQ号为:

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

去重就简单了:

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

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

方法二:hashmap

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

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

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

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

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

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

方法三:文件切割

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

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

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

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

方法四:bitmap

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

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

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

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

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

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

由此可见,一个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] = 1bitmapFlag[567] = 1bitmapFlag[123] = 1bitmapFlag[890] = 1

实际上就是:

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

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

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

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

扩展练习一

文件中有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号码。

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

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/106310.html

(0)

相关推荐

  • 宣布二胎出生心情说说句子,后悔要二胎的句子

    一、2021年5月18日,老二出生了,因为我丈母娘和我妈一直告诉我老婆,生了就可以瘦肚子,把生老大没有收下去的肚子收下去。而且可以给猴子和哈士奇结合体的老大找个伴……印象最深的一句话就是“要生快生……”我选了条件最好的第一人民医院,订了最好的单人房间,一辈子又生几次孩子呢?一个人照顾她们母子俩八天,然后开开心心开车回家。本以为一切都向着好的方向发展,没想到才过了两天,孩子就开始拉肚子,一天十几次,当时还以为是“忌肚子,”医生也这么说。然后第三天发烧38℃。大半夜的开车赶紧送到第一人民医院,住进了新生儿科。说是单肺肺炎感染。又住了一个礼拜,抱出院。以为一切万事大吉,又过了十天不到,又开始发高烧,这次不敢再送去,换了本地的第二人民医院,医了六天,天天跑去看,天天发高烧,第六天孩子已经处于昏睡状态了。医生告诉我说,“要升级治疗,原来用两种抗生素的,现在用四种抗生素,还要吊免疫球蛋白。”孩子才21天,我和老婆越合计,觉得越不对,赶紧要求转院。左求,右求吧。昆明儿童医院床位满,不收。贵阳医科大学附属医院需要做评估,而且只能去普通病房或者ICU,派车来接的话需要3600元。可是一听孩子21天了,就说超过国家规定的年纪,进不了新生儿科。最后是曲靖妇幼保健院收的,晚上10点过到的曲靖吧,媳妇一天月子没做过,陪着我天南海北的跑。回想她在车上流的眼泪,我至今觉得愧疚难当。还有装孩子的保温箱,还有那寒冷的不属于我的夜空。第二天早上,我们再来问,孩子高烧已经退下来了。阿弥陀佛。住了21天,孩子终于痊愈了。开心。尽管欠了六万多快。哈哈。

    生活 2021年12月8日
  • 孩子放不下糖果,但除了增加肥胖的概率,还会影响其他身体机能。

    糖果是小孩子最喜欢的食物之一,几乎每个孩子都爱吃糖。大人想要哄孩子开心的话,最简单有效的方法就是拿出一颗糖。虽说糖果很甜很美味,但是吃多了的确会对身体不好,很多家长也都知道给孩子吃太多糖并不好,会容易让牙齿坏掉。但是吃糖过多的后果可并没有那么简单,长期过多地摄入糖分,对于孩子的生长发育会带来非常多威胁。

    2021年11月8日
  • 刀赛诺登山王电动摩托车评价:爬坡动力足,续航时间长,以丘陵山路为主。

    对于一些丘陵地区的用户来说,在选择电动车时,会优先考虑车辆动力。而对此,以小刀为代表的电动车企业则加大了对大功率车型的打造力度,其在最近就推出了一款新电摩赛诺爬山王。据了解,该车不仅爬坡动力足,而且续航性能出色。那么,具体配置如何呢?

    科技 2021年10月30日
  • “班里有25个孩子,18个是男宝!”入学第一天,妈妈为了女儿辍学了。

    我不知道你有没有注意到。在中小学或幼儿园的很多班级中,男生人数明显多于女生,男女比例失调的情况似乎依然很严重。 10月10日到1010年,我侄女小丽的女儿今年上幼儿园了。因为闺蜜叫...

    生活 2021年10月24日