大量数据和空间限制

1、只用2GB内存在20亿个整数中找到出现次数最多的数
题目:有一个包含20亿个全是32位整数的大文件,在其中找到出现次数最多的数,内存限制为2GB
分析解答
使用哈希表对出现的每一个数进行词频统计。哈希表的key是某一个整数,value是这个数出现的次数。
若一个数出现了20亿次,那么32位整数用哈希表进行存储时,key需要占用4B的空间,value也是4B.那么哈希表的一条记录(key,value)需要占用8B,当哈希表记录数为20亿个时,至少需要1.6GB的内存。
若20亿个数中不同的数超过2亿种,最极端情况是20亿个数都并不相同,那么在哈希表中可能需要产生20亿条记录,这样内存会不够用,所以一次性用哈希表统计20亿个数的方法不可取。
解决办法是 把包含20亿个数的大文件用哈希函数分成16个不同的小文件 ,假设哈希函数足够好以及哈希函数的性质,同一种数不可能被哈希到不同的小文件上,同时每个小文件中不同的数一定不会大于2亿种。然后对每一个小文件用哈希表来统计每种数出现的次数,这样我们就得到了16个小文件中各自出现次数最多的数,还有各自的次数统计。接下来只要选出这16个小文件中各自的第一名中谁出现次数最多即可。

2、找到100亿个 URL 中重复的 URL 以及搜索词汇中的top K问题
题目、 有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL。
常规方法
把大文件通过哈希函数分配到及其,或者通过哈希函数把大文件拆分成小文件。一直进行这种划分,直到划分的结果满足资源限制的要求。记得限制条件的考虑,比如资源上的限制,包括内存,计算时间等。
哈希分流到多台机器
将100亿字节的大文件通过哈希函数分配到100台机器上,然后每一台机器分别统计给自己的URL中是否有重复的URL,同时哈希函数的性质决定了同一条URL不可能分配给不同的机器;
处理百亿数据量的词汇文件
如果在分流后发现每台机器上面的数据依旧很大,那么可以用哈希函数将每台机器的分流文件拆分成更小文件进行处理。处理每一个小文件时,哈希表通过统计每种词及其词频,哈希表记录建立完成后,在遍历哈希表,遍历哈希表时使用大小为100的小根堆来选出每一个小文件的top100(整体未排序的100)。每一个小文件都有自己词频的小根堆,将小根堆里面的词按照词频排序,就 得到了每个小文件的排序后top100 ,。然后把各个小文件排序后的top100进行外排序或者继续利用小根堆,就可以 选出每台机器上的top100 .不同机器之间的top100再进行外排序或者继续利用小根堆, 最终求出整个百亿数据量中的 top100
哈希表统计每个机器中的每个小文件
或者在单机上将大文件通过哈希函数拆分成1000个小文件,对每一个小文件再利用哈希表遍历,找出重复的URL;
最小堆
或者在分给机器或拆完文件之后,进行排序,排序过后看是否有重复的URL出现。


3在100万个数中找最大的前100个

思路:
①分块查找
把100万个数分成100份,每份1万个数。先分别找出每1万个数里面的最大的数,然后比较。找出100个数中的最大的数和最小的数,取最大数的这组的第二大的数,与最小的数进行比较
②先取出前100个数,维护一个100个数的最小堆,遍历一遍剩余的元素,在此过程中维护堆就可以了。具体步骤如下:
step1:取前m个元素(例如m=100),建立一个小顶堆。保持一个小顶堆得性质的步骤,运行时间为O(lgm);建立一个小顶堆运行时间为m*O(lgm)=O(m lgm);       
step2:顺序读取后续元素,直到结束。每次读取一个元素,如果该元素比堆顶元素小,直接丢弃
如果大于堆顶元素,则用该元素替换堆顶元素,然后保持最小堆性质。最坏情况是每次都需要替换掉堆顶的最小元素,因此需要维护堆的代价为(N-m)*O(lgm);
最后这个堆中的元素就是前最大的10W个。时间复杂度为O(N lgm)。
 
③根据快速排序划分的思想
(1) 递归对所有数据分成[a,b)b(b,d]两个区间,(b,d]区间内的数都是大于[a,b)区间内的数
(2) 对(b,d]重复(1)操作,直到最右边的区间个数小于100个。注意[a,b)区间不用划分
(3) 返回上一个区间,并返回此区间的数字数目。接着方法仍然是对上一区间的左边进行划分,分为[a2,b2)b2(b2,d2]两个区间,取(b2,d2]区间。如果个数不够,继续(3)操作,如果个数超过100的就重复1操作,直到最后右边只有100个数为止。

猜你喜欢

转载自blog.csdn.net/qq_38844645/article/details/80494750