19、在 2.5 亿个整数中找出不重复的整数,注,内存不足以容纳这 2.5 亿个整数。
1)方案 1:采用 2-Bitmap(每个数分配 2bit,00 表示不存在,01 表示出现一次,
10 表示多次,11 无意义)进行,共需内存 2^32 * 2 bit=1 GB 内存,还可以接受。然后
扫描这2.5 亿个整数,查看 Bitmap 中相对应位,如果是 00 变 01,01 变 10,10 保
持不变。所描完事后,查看bitmap,把对应位是 01 的整数输出即可。
2)方案 2:也可采用与第 1 题类似的方法,进行划分小文件的方法。然后在小文件中
找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。
20、给 40 亿个不重复的 unsigned int 的整数,没排过序的,然后再给一
个数,如何快速判断这个数是否在那40 亿个数当中?
1)方案 1:oo,申请 512M 的内存,一个 bit 位代表一个 unsigned int 值。读入 40
亿个数,设置相应的bit 位,读入要查询的数,查看相应 bit 位是否为 1,为 1 表示存
在,为0 表示不存在。
2)方案 2:这个问题在《编程珠玑》里有很好的描述,大家可以参考下面的思路,探讨
一下:又因为2^32 为 40 亿多,所以给定一个数可能在,也可能不在其中; 这里我们把 40 亿个数中的每一个用 32 位的二进制来表示 ,假设这 40 亿个数开始放在一个文件
中。然后将这40 亿个数分成两类:
1.最高位为 0
2.最高位为 1
并将这两类分别写入到两个文件中,其中一个文件中数的个数<=20 亿,而另一个>=20
亿(这相当于折半了);与要查找的数的最高位比较并接着进入相应的文件再查找再然后
把这个文件为又分成两类:
1.次最高位为 0
2.次最高位为 1
并将这两类分别写入到两个文件中,其中一个文件中数的个数<=10 亿,而另一个>=10
亿(这相当于折半了);与要查找的数的次最高位比较并接着进入相应的文件再查找。
.....
以此类推,就可以找到了,而且时间复杂度为 O(logn),方案 2 完。
3)附:这里,再简单介绍下,位图方法: 使用位图法判断整形数组是否存在重复 ,判断集
合中存在重复是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,
这时双重循环法就不可取了。
位图法比较适合于这种情况,它的做法是按照集合中最大元素max 创建一个长度为
max+1 的新数组,然后再次扫描原数组,遇到几就给新数组的第几位置上 1,如遇到 5 就
给新数组的第六个元素置1,这样下次再遇到 5 想置位时发现新数组的第六个元素已经是
1 了,这说明这次的数据肯定和以前的数据存在着重复。这 种给新数组初始化时置零其后
置一的做法类似于位图的处理方法故称位图法。它的运算次数最坏的情况为2N。如果已知
数组的最大值即能事先给新数组定长的话效率还能提高一倍。
21、怎么在海量数据中找出重复次数最多的一个?
1)方案 1:先做 hash,然后求模映射为小文件,求出每个小文件中重复次数最多的一
个,并记录重复次数。然后找出上一步求出的数据中重复次数最多的一个就是所求(具体参
考前面的题)。
22、上千万或上亿数据(有重复),统计其中出现次数最多的钱 N 个数据。
1)方案 1:上千万或上亿的数据,现在的机器的内存应该能存下。所以考虑采用
hash_map/搜索二叉树/红黑树等来进行统计次数。然后就是取出前 N 个出现次数最多的
数据了,可以用第2 题提到的堆机制完成。
23、一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前 10 个
词,给出思想,给出时间复杂度分析。
1)方案 1:这题是考虑时间效率。用 trie 树统计每个词出现的次数,时间复杂度是
O(n*le)(le 表示单词的平准长度)。然后是找出出现最频繁的前 10 个词,可以用堆来实
现,前面的题中已经讲到了,时间复杂度是O(n*lg10)。所以总的时间复杂度,是 O(n*le)
与O(n*lg10)中较大的哪一 个。
24、100w 个数中找出最大的 100 个数。
1)方案 1:在前面的题中,我们已经提到了,用一个含 100 个元素的最小堆完成。复
杂度为O(100w*lg100)。
2)方案 2:采用快速排序的思想,每次分割之后只考虑比轴大的一部分,知道比轴大的一部 分在比 100 多的 时候,采 用传统排 序算法 排序,取 前 100 个。 复杂度为
O(100w*100)。
3)方案 3:采用局部淘汰法。选取前 100 个元素,并排序,记为序列 L。然后一次扫
描剩余的元素x,与排好序的 100 个元素中最小的元素比,如果比这个最小的 要大,那
么把这个最小的元素删除,并把x 利用插入排序的思想,插入到序列 L 中。依次循环,直
到扫描了所有的元素。复杂度为O(100w*100)。
25、有一千万条短信,有重复,以文本文件的形式保存,一行一条,有重复。 请用 5 分
钟时间,找出重复出现最多的前10 条。
1)分析: 常规方法是先排序,在遍历一次,找出重复最多的前 10 条。但是排序的算
法复杂度最低为nlgn。
2)可以设计一个 hash_table, hash_map<string, int>,依次读取一千万条短信,加载
到hash_table 表中,并且统计重复的次数,与此同时维护一张最多 10 条的短信表。 这
样遍历一次就能找出最多的前10 条,算法复杂度为 O(n)。
全部评论
(0) 回帖