排序问题
1、100G 数据,只有 100M 内存,怎么排序?
思路:
使用多路归并排序
100G 数据,按照 100M 内存拆分,然后排序有序的数据,然后写入到 file1,file2…file100。
多路归并:
每次取出当前所有文件中的最小值,存入最终的大文件中。
第一回合:
从 file1,file2,file3……file100.取出第一个数。及最小的。所有的初始指针都是第一行。 min1=min(min1=min(fil1,file2,file3……file100);file2,file3……file100);min1 写入到大数据文件。大数据行数指针+1。min1对应的行数指针+1。
第二回合:
从file1,file2,file3……file100.取出第一个数。及最小的。所有的初始指针都是第一行。min2 = min(fil1,fil1,file2,file3……file100); min2写入到大数据文件。大数据行数指针+1。min2写入到大数据文件。大数据行数指针+1。min2 对应的行数指针+1。
2、
大数据处理问题
查找
1、10亿个正整数,只有其中1个数重复出现过,要在O(n)的时间里面找出这个数,内存要尽可能少(小于200M)?
思路:位图法
(1)首先看一下10亿个正整数,正整数可以表示的范围为1到2的31次方-1。
位图法也就是对于出现的数,其中每1bit代表这个数,如果该位为1,则说明该数出现;如果该位为0,则说明该数没有出现。
10亿也就是1
10
9,2
31次方=2
1024
1024
1024>20亿, 将10,0000,0000处以8388608得到119.20928955078125,也就是差不多120M的内存,可以表示全10亿的数。
所以可以建立120M的一个位图,将其所有位设置为0,然后开始遍历这10亿个整数,每遍历一个,则对应到位图中相应的位置1,如果对应到位图中相应的位已经置1了,则说明这个数是要找的那个重复的数。用这种方法,最多就是遍历一遍,将这个10亿个正整数遍历完。
而使用的内存为120M左右。
2、如果有一个20g的日志文件,日志文件记录着用户访问过的url,每一行为一个url,给你一台512M的主机,找出出现次数最多的10个url?
思路1:
(1)Top K算法:使用堆排序算法+大顶堆+10个元素的数组
思路2:
(2)分治法
- IP地址最多有2^32=4G种取值情况,所以不能完全加载到内存中处理;
- 可以考虑采用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址;
- 对于每一个小文件,可以构建一个IP为key,出现次数为value的Hash map,同时记录当前出现次数最多的那个IP地址;
- 可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的IP;
亿级排序
1、一个最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数)的文件,其中每个数都小于等于n,且n=10^7。得到按从小到大升序排列的包含所有输入的整数的列表?
思路:
(1)磁盘归并多路排序
先将所有数据分成多个小文件,多个小文件采用内部排序后,再用多路合并排序完成排序输出。
总数据为n, 内存中采用内部排序最多m。先分成n/m个小文件,再内部排序,第三部读取所有小文件,每次将最小的数输出即可。
(2)bitmap排序
在内存中开10^7比特,均初始化为0,若出现则设置为1,输出为1的数即可。
智力题
1、赛马找最快
25匹马5条跑道找最快的3匹马,需要跑几次?答案:7
64匹马8条跑道找最快的4匹马,需要跑几次?答案:11
25匹马5条跑道找最快的5匹马,需要跑几次?答案:最少8次最多9次
2、砝码称轻重
-
有一个天平,九个砝码,其中一个砝码比另八个要轻一些,问至少要用天平称几次才能将轻的那个找出来? 答案:2次
-
十组砝码每组十个,每个砝码都是10g重,但是现在其中有一组砝码每个都只有9g重,现有一个能显示克数的秤,最少称几次能找到轻的那组? 答案:1次
3、药瓶毒白鼠
首先一共有1000瓶,2的10次方是1024,刚好大于1000,也就是说,1000瓶药品可以使用10位二进制数就可以表示。从第一个开始:
第一瓶 : 00 0000 0001
第二瓶: 00 0000 0010
第三瓶: 00 0000 0011
……
第999瓶: 11 1111 0010
第1000瓶: 11 1111 0011
需要十只老鼠,如果按顺序编号,ABCDEFGHIJ分别代表从低位到高位每一个位。 每只老鼠对应一个二进制位,如果该位上的数字为1,则给老鼠喝瓶里的药。
观察,若死亡的老鼠编号为:ACFGJ,一共死去五只老鼠,则对应的编号为 10 0110 0101,则有毒的药品为该编号的药品,转为十进制数为:613号。(这才是正解,当然前提是老鼠还没被撑死)
4、绳子两头烧
现有若干不均匀的绳子,烧完这根绳子需要一个小时,问如何准确计时15分钟,30分钟,45分钟,75分钟。。。
15:对折之后两头烧(要求对折之后绑的够紧,否则看45分钟解法)
30:两头烧
45:两根,一根两头烧一根一头烧,两头烧完过了30分钟,立即将第二根另一头点燃,到烧完又过15分钟,加起来45分钟
75:=30+45
。。。