【左神算法笔记】资源限制类题目

技巧:

在这里插入图片描述

题目一:范围统计搜索-位图

32位无符号整数的范围是0~4,294,967,295( 2 32 − 1 2^{32}-1 2321

现有一个正好包含40亿个无符号整数的文件,所以一定有没出现过的无符号整数

如何使用1GB内存找到没有出现的数?

【进阶】内存为3KB,找到一个没有出现的数

分析

没有硬盘空间,没办法用哈希分流做,用位图做

32位无符号整数个数为 2 32 2^{32} 232,占用空间为 2 32 / 8 2^{32}/8 232/8字节byte=500MB

所以对于原问题,申请一个大小500mb左右的int数就可以解决,出现过的数对应位置为1,则为0的位对应无符号数就是没出现过的

对于进阶问题,3KB可以容纳数组unsigned int[512] arr,那么可以把 2 32 2^{32} 232个无符号整数等分为512份,每份 2 23 2^{23} 223个数

注意:每个unsigned int占用4Byte

那么数组arr[0]表示0~ 2 23 − 1 2^{23}-1 2231这些数出现的总次数

arr[1]表示 2 23 2^{23} 223~ 2 24 − 1 2^{24}-1 2241这些数出现的总次数

···············

以此类推

那么一定有某个arr[i]小于 2 23 2^{23} 223,那我就知道缺的数字来自哪个范围了

接下来在这个范围上继续划分为512份,继续统计词频,然后有知道了一个更小的范围

周而复始,一定可以找到一个缺少的数字

再进一步,使用有限几个变量解决

那么不断二分 2 32 2^{32} 232即可,其实就是把512换成2

32次二分就可以找到解

题目二

有一个包含100亿个URL的大文件,假设每个URL占用64B,找出其中所有重复的URL

1、hash分流

将所有url哈希取模后,放入不同的文件,统计每个文件的重复url

2、布隆过滤器

插入的过程中也查询,查询到已经插入过的url就记录在一个文件中(有失误率)

【补充】

某搜索公司一天的用户搜索词汇达到百亿数据量,设计一种求出每天热门top100词汇的可行办法

首先用hash函数分流成多个小文件,每个小文件的top100可以很容易的统计出来

下面讲使用堆来根据小文件的top100算出总的top100

每个小文件的url根据词频形成大根堆

下面把每个大根堆的堆顶单独拿出来,组织成一个总大根堆

弹出总大根堆的堆顶,找到他所属的小文件大根堆,pop小堆的堆顶,然后把新的小堆堆顶放入总大根堆

题目三

32位无符号整数的范围是0~4,294,967,295( 2 32 − 1 2^{32}-1 2321

现有一个正好包含40亿个无符号整数的文件,如何使用1GB内存找到所有出现了2次的数?

【进阶】内存为10MB,找到这40亿个数的中位数

万能解法:hash函数分流,将所有数分到若干小文件中去,再单独对小文件内容计数

位图:用2个位表示数出现的状态,00无意义,01表示出现0次,01表示出现1次,10表示出现2次,11就是出现多于2次

所以申请 2 32 ∗ 2 / 8 2^{32}*2/8 2322/8Byte= 2 30 2^{30} 230B=1GB大小的空间作为位图

【进阶】范围统计思想,10MB内存可以容纳unsigned int[ 2 20 2^{20} 220],将40亿个数分为 2 20 2^{20} 220份,每个arr[i]就存放了第i份数出现的频数,那么找到第20亿个数出现的范围,再继续划分小范围,最终就可以定位到中位数所在的很小范围内

题目四:腾讯原题

10GB的文件内存储了无序的int数据,如何利用5GB内存空间,对数据进行排序,生成一个有序的文件?

使用堆!

一个小根堆,内容存放数据本身和它的词频(共8Byte),根据数据本身排序

堆中还有一些索引信息,所以把一条记录看成16Byte

5GB内存可存放的记录数量为5GB/16B= 5 ∗ 2 26 > 2 28 5*2^{26}>2^{28} 5226>228
int的大小为 − 2 31   2 31 − 1 -2^{31}~2^{31}-1 231 2311
2 32 2^{32} 232个数等分为 2 28 2^{28} 228份,每份范围是 2 4 2^4 24

小根堆先统计最低范围上的数字的词频

统计完以后,按照这些数出现的次数输出到一个文件中去

然后继续下一个范围的统计,再输出

······

最终统计完所有小范围的数,也全部输出了,排序就结束了

还有另一种思路,不使用范围,而是每次统计最小的几个数的词频,并且用一个阈值来限制本次统计的词的最小值(也就是已经统计完的词的最大值)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值