【数据结构与算法|大数据算法题目及其解题技巧】1) 哈希函数可以把数据按照种类均匀分流
2) 布隆过滤器用于集合的建立与查询,并可以节省大量空间
3) 一致性hash解决数据服务器的负载管理问题
4) 利用并查集结构做岛问题的并行计算
5)位图解决某一范围上数字的出现情况,并可以节省大量空间
6)利用分段统计思想、并进一步节省空间
7)利用堆、外排序来做多个处理单元的结果合并
题目一:32位无符号整数的范围是0~4,294,967,295,现在有一个正好包含40亿个无符号整数的文件,所以在整个范围中必然存在没出现过的数。可以使用最多1GB的内存,怎么找到所有未出现过的数?
解决:用位数组 0-2^32-1这个数中只出现40亿个。一个字节8bit,也就是一个字节可以表示8个数。用01表示出现过没有就行。40亿,就要用500000000bit。也就是476MB,差不多0.5G,所以绰绰有余。
进阶:如果用3KB的大小,找出任意一个没有出现过的数字?
(不管给多少空间,用此办法都可以)首先在3KB(3000/4=700多,也就是能申请长度700多的整型数组 )上找到一个离2的次方最接近的一个数,也就是2^9 = 512 离得最近(为什么要2的次方,因为0~2^32次方个数能够按照这个数整分。也就是2^32/2^9= 8388608 )。申请一个数组长度为512的。然后每一个位置上表示的含义是:40亿的数字按照512的大小均分,分成了8388608份,那么0~8388608 这些数就放在第一个位置上(8388608 ~8388608x2是第二个位置表示的值,怎么统计这个范围的数出现了几次?用这个数除以8388608,比如 1/8388608 = 0,那么1这个数就是属于这个数组中的0号位置,就把0号位置的次数加1),然后统计第一个位置上这个数出现的次数是不是8388608个。如果不是,说明一定在这个范围内有一个数字没有出现,然后再把8388608按照512的大小进行均分,重复上面的操作,一定可以找出那个没有出现的数字。
如果只给3个变量,怎么找出?把40亿进行二分,少数字那边继续二分找。同样的原理。
题目二:有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL
(补充):某搜索公司一天的用户搜索词汇是海量的(百亿数据量),请设计一种求出每天热门Top100词汇的可行方法。
1)用哈希函数然后再取模,进行分类,放到一堆小文件中去,然后再从一堆小文件中继续哈希。
或者用布隆过滤器也行。
2)补充的热门词汇问题可以用二维大根堆来实现。每次弹出一个大根堆中的堆顶元素然后再放到一个大根堆中去。
题目三:32位无符号整数的范围是0~4294967295,现在有40亿个无符号整数,可以使用最多1GB的内存,找出所有出现了两次的数。
1)用哈希函数再取模分类到小文件的方式
2)用位图,00表示出现了0次,01出现了1次,10出现了两次,11出现了两次以上。同题目一一样。(2^32) * 2/ 8 ,其实就是题目一中一个位表示一个数改成现在要两位来表示出现的次数。差不多要0.9点多GB,是可以完成要求的。
题目四:40亿个数中,只有10KB如果找出中位数?
同样用位图,统计词频,找出累加词频刚好到20亿的这个数,
文章图片
题目五:有10GB大文件里面存放着无序有符号的整数,给你5GB空间,如何把这个无序变成有序。(腾讯面试题)
思路:(先分桶再排序)
1)用小根堆(每一个元素有数值,次数两个属性)来作为媒介遍历每一个文件段(5GB可以申请可以存储多大的小根堆),每一个小段进入小根堆后,输出小根堆就可以了,然后总结果就是依次排序。
2)用大根堆。简单例子:总共有10个数,创建一个只存放3个数的大根堆。然后依次遍历这十个数,这个大根堆里面存放的是10个数中最小的3个数。然后输出有序的最小的3个数。此时记录排完序的3个数中最大的那个数Y,清空大根堆后,继续去遍历这10个数,但是小于Y的就不要遍历了,然后找出最小的3个数,然后输出,一直重复就可以了。
推荐阅读
- spring-boot随记
- java|Spring Boot 学习随记
- java|Spring Cloud 随记
- java|《Spring Boot 实战》随记
- 一套互联网公司理想架构,建议收藏。。。
- LeetCode编程题解法汇总|力扣解法汇总432-全 O(1) 的数据结构
- JavaWeb|一篇学会HttpServletRequest
- JavaWeb|Servlet----ServletContext
- JavaWeb|HttpServlet源码分析