如何判断一个数是否在40亿个整数中
2018-09-05 18:32
507 查看
【面试现场】
题目:我有40亿个整数,再给一个新的整数,我需要判断新的整数是否在40亿个整数中,你会怎么做?
![](https://oscimg.oschina.net/oscnet/08213fffa01a450d1f9d1e78cac7ee01596.jpg)
![](https://oscimg.oschina.net/oscnet/1abc999c7ac7c312cb1af27a2b0dbcd983b.jpg)
![](https://oscimg.oschina.net/oscnet/b32b1d17a6da61feb303bd1d8b679737ee4.jpg)
![](https://oscimg.oschina.net/oscnet/bc8d1310b2f1347cea801e5482acfb9e0dc.jpg)
![](https://oscimg.oschina.net/oscnet/6984e7a81a3f685b6db552b8407c7edacd7.jpg)
![](https://oscimg.oschina.net/oscnet/4d79122a2b568a8c37d3c04457ac0dc2dd7.jpg)
![](https://oscimg.oschina.net/oscnet/e58624fb8ddb3b23511c8d44bf1cc9c64b9.jpg)
![](https://oscimg.oschina.net/oscnet/10aa12dad09eace1a07e46a761b38637ca9.jpg)
![](https://oscimg.oschina.net/oscnet/dc0f82080c872515dec80ab6bfe7cdf37e3.jpg)
![](https://oscimg.oschina.net/oscnet/eae5cade66e051e7cf1c63de8173a2a3de8.jpg)
![](https://oscimg.oschina.net/oscnet/03d4fec56ba8b6f515810fc4c6918afd549.jpg)
【请教大神】
小史回到学校,把面试的情况和计算机学院的吕老师说了一下。
![](https://oscimg.oschina.net/oscnet/9e7b110fc81f9efe3e64a5f919fc02f0300.jpg)
![](https://oscimg.oschina.net/oscnet/43b08970132b5e2c5aac1dadf5552b6d0d8.jpg)
小史忙拉着吕老师问,为什么我说分8次加载数据,面试官会说太慢了呢?
吕老师:哈哈,从磁盘加载数据是磁盘io操作,是非常慢的,你每次都要加载这么大的数据,还要8次,我估计你找一个数的时间可以达到分钟甚至小时级了。
![](https://oscimg.oschina.net/oscnet/051536dc781f3d99f5eb494bbda3ca861d2.jpg)
小史:那如果是你,你会怎么办呢?
吕老师:其实面试官已经提示得比较明显了,他说给你一批机器,就是暗示你可以用分布式算法。你把数据分散在8台机器上,然后来一个新的数据,8台机器一起找,最后再汇总结果就行了。
![](https://oscimg.oschina.net/oscnet/691bf998483009b9738bd9629562a77e2ea.jpg)
小史:这样的话能快多少?
吕老师:这样应该能达到秒级。小史,你可以自己分析分析。
小史:我想想……哦,这样做的话,因为每台机器都可以一次性把数据读入内存,在比较的时候不用来回加载数据了,所以可以节省加载数据的开销!这真是个好办法。
【更好方案】
吕老师:其实这并不是最好方法,我这还有一种毫秒级的方法,想不想知道啊?
小史:当然想啊,快教教我。
![](https://oscimg.oschina.net/oscnet/2debf2102868effbadce3f003e4b6d6f28c.jpg)
小史:哦,对哦,这样我就申请40亿个位就好了,新的数转换成一个位,然后判断一下这个位是0还是1就行了。
吕老师:小史啊,考虑问题要考虑清楚啊,如果是40亿个位,那么这40亿个位哪些是0,哪些是1呢?来了一个新的数,怎么判断是否在40亿个位之中?
![](https://oscimg.oschina.net/oscnet/607d67f44f22c589ae31ece5cd75bf68fd7.jpg)
小史:我想想,对啊,40亿个位,40亿个数,那么每个位都是1,这。。。
吕老师:其实你可以想想,32位int的范围,总共就是2的32次方,大概42亿多点。所以你可以申请2的32次方个位。
小史:意思是我把整个整数范围都覆盖了,哦,对哦。这样一来,就可以做了,1代表第一个位,2代表第二个位,2的32次方代表最后一个位。40亿个数中,存在的数就在相应的位置1,其他位就是0。
![](https://oscimg.oschina.net/oscnet/6e6b5217a28dd2097b37e825adca7f60a84.jpg)
吕老师:没错,那来了一个新的数呢?
小史:新的数就去找相应的位,比如来了一个1234,就找一下第1234位,如果是1就存在,是0就不存在啦。
吕老师:没错,那么这样的话,需要多大内存呢?
小史:我想想啊,2的32次方个位,相当于2的29次方个字节,哇,才500MB,真是节省了不少内存呢。
![](https://oscimg.oschina.net/oscnet/05946ae22c93cde1c1d3a4afc534c242c34.jpg)
小史:这么厉害的算法,你是怎么想到的?
![](https://oscimg.oschina.net/oscnet/f0a5b64fb865a25c5b8134307eec968441b.jpg)
吕老师:其实这是一种非常有名的大数据算法,叫位图法,英文名叫bitmap。顾名思义,就是用位来表示状态,从而节省空间。明天正好我有一节课,就讲位图法,你可以来听一听。
【吕老师的课】
第二天,吕老师开始上课,他一开始就抛出了小史遇到的面试题。
吕老师:同学们,这道面试题,大家有什么思路吗?
话音刚落,蛋哥就站起来回答。蛋哥是吕老师最得意的门生,以思维活跃著称。
![](https://oscimg.oschina.net/oscnet/0ab2da864a4d8cdfb6d0d558ca95c5bf61e.jpg)
蛋哥:我觉得可以这样。首先,32位int的范围是42亿,40亿整数中肯定有一些是连续的,我们可以先对数据进行一个外部排序,然后用一个初始的数和一个长度构成一个数据结构,来表示一段连续的数,举个例子。
如果数据是1 2 3 4 6 7……这种的,那么可以用(1,4)和(6,2)来表示,这样一来,连续的数都变成了2个数表示。
来了一个新数之后,就用二分法进行查找了。
这样一来,最差情况就是2亿多的断点,也就是2亿多的结构体,每个结构体8个字节,大概16亿字节,1.6GB,在内存中可以放下。
![](https://oscimg.oschina.net/oscnet/22c6be5ac2ff350e8e51091314357aa0f6a.jpg)
吕老师:嗯,非常好,不仅给出了方案,还能主动分析空间和可行性。
小史听完后深感佩服,问题的解决方法绝对不止一种,只要肯动脑筋,即使没有学过bitmap算法,也能有别的方法来解决问题。
【课后】
下课后,小史又找到吕老师。
![](https://oscimg.oschina.net/oscnet/cc7a22d4e931a6113b17e53439e205d1cb8.jpg)
![](https://oscimg.oschina.net/oscnet/5634029aba92dcc33874be3b87e7ec84250.jpg)
吕老师:但是你的理解能力还是很强的,很多东西一听就懂,这可不是谁都能做到的。
题目:我有40亿个整数,再给一个新的整数,我需要判断新的整数是否在40亿个整数中,你会怎么做?
![](https://oscimg.oschina.net/oscnet/08213fffa01a450d1f9d1e78cac7ee01596.jpg)
![](https://oscimg.oschina.net/oscnet/1abc999c7ac7c312cb1af27a2b0dbcd983b.jpg)
![](https://oscimg.oschina.net/oscnet/b32b1d17a6da61feb303bd1d8b679737ee4.jpg)
![](https://oscimg.oschina.net/oscnet/bc8d1310b2f1347cea801e5482acfb9e0dc.jpg)
![](https://oscimg.oschina.net/oscnet/6984e7a81a3f685b6db552b8407c7edacd7.jpg)
![](https://oscimg.oschina.net/oscnet/4d79122a2b568a8c37d3c04457ac0dc2dd7.jpg)
![](https://oscimg.oschina.net/oscnet/e58624fb8ddb3b23511c8d44bf1cc9c64b9.jpg)
![](https://oscimg.oschina.net/oscnet/10aa12dad09eace1a07e46a761b38637ca9.jpg)
![](https://oscimg.oschina.net/oscnet/dc0f82080c872515dec80ab6bfe7cdf37e3.jpg)
![](https://oscimg.oschina.net/oscnet/eae5cade66e051e7cf1c63de8173a2a3de8.jpg)
![](https://oscimg.oschina.net/oscnet/03d4fec56ba8b6f515810fc4c6918afd549.jpg)
【请教大神】
小史回到学校,把面试的情况和计算机学院的吕老师说了一下。
![](https://oscimg.oschina.net/oscnet/9e7b110fc81f9efe3e64a5f919fc02f0300.jpg)
![](https://oscimg.oschina.net/oscnet/43b08970132b5e2c5aac1dadf5552b6d0d8.jpg)
小史忙拉着吕老师问,为什么我说分8次加载数据,面试官会说太慢了呢?
吕老师:哈哈,从磁盘加载数据是磁盘io操作,是非常慢的,你每次都要加载这么大的数据,还要8次,我估计你找一个数的时间可以达到分钟甚至小时级了。
![](https://oscimg.oschina.net/oscnet/051536dc781f3d99f5eb494bbda3ca861d2.jpg)
小史:那如果是你,你会怎么办呢?
吕老师:其实面试官已经提示得比较明显了,他说给你一批机器,就是暗示你可以用分布式算法。你把数据分散在8台机器上,然后来一个新的数据,8台机器一起找,最后再汇总结果就行了。
![](https://oscimg.oschina.net/oscnet/691bf998483009b9738bd9629562a77e2ea.jpg)
小史:这样的话能快多少?
吕老师:这样应该能达到秒级。小史,你可以自己分析分析。
小史:我想想……哦,这样做的话,因为每台机器都可以一次性把数据读入内存,在比较的时候不用来回加载数据了,所以可以节省加载数据的开销!这真是个好办法。
【更好方案】
吕老师:其实这并不是最好方法,我这还有一种毫秒级的方法,想不想知道啊?
小史:当然想啊,快教教我。
![](https://oscimg.oschina.net/oscnet/2debf2102868effbadce3f003e4b6d6f28c.jpg)
小史:哦,对哦,这样我就申请40亿个位就好了,新的数转换成一个位,然后判断一下这个位是0还是1就行了。
吕老师:小史啊,考虑问题要考虑清楚啊,如果是40亿个位,那么这40亿个位哪些是0,哪些是1呢?来了一个新的数,怎么判断是否在40亿个位之中?
![](https://oscimg.oschina.net/oscnet/607d67f44f22c589ae31ece5cd75bf68fd7.jpg)
小史:我想想,对啊,40亿个位,40亿个数,那么每个位都是1,这。。。
吕老师:其实你可以想想,32位int的范围,总共就是2的32次方,大概42亿多点。所以你可以申请2的32次方个位。
小史:意思是我把整个整数范围都覆盖了,哦,对哦。这样一来,就可以做了,1代表第一个位,2代表第二个位,2的32次方代表最后一个位。40亿个数中,存在的数就在相应的位置1,其他位就是0。
![](https://oscimg.oschina.net/oscnet/6e6b5217a28dd2097b37e825adca7f60a84.jpg)
吕老师:没错,那来了一个新的数呢?
小史:新的数就去找相应的位,比如来了一个1234,就找一下第1234位,如果是1就存在,是0就不存在啦。
吕老师:没错,那么这样的话,需要多大内存呢?
小史:我想想啊,2的32次方个位,相当于2的29次方个字节,哇,才500MB,真是节省了不少内存呢。
![](https://oscimg.oschina.net/oscnet/05946ae22c93cde1c1d3a4afc534c242c34.jpg)
小史:这么厉害的算法,你是怎么想到的?
![](https://oscimg.oschina.net/oscnet/f0a5b64fb865a25c5b8134307eec968441b.jpg)
吕老师:其实这是一种非常有名的大数据算法,叫位图法,英文名叫bitmap。顾名思义,就是用位来表示状态,从而节省空间。明天正好我有一节课,就讲位图法,你可以来听一听。
【吕老师的课】
第二天,吕老师开始上课,他一开始就抛出了小史遇到的面试题。
吕老师:同学们,这道面试题,大家有什么思路吗?
话音刚落,蛋哥就站起来回答。蛋哥是吕老师最得意的门生,以思维活跃著称。
![](https://oscimg.oschina.net/oscnet/0ab2da864a4d8cdfb6d0d558ca95c5bf61e.jpg)
蛋哥:我觉得可以这样。首先,32位int的范围是42亿,40亿整数中肯定有一些是连续的,我们可以先对数据进行一个外部排序,然后用一个初始的数和一个长度构成一个数据结构,来表示一段连续的数,举个例子。
如果数据是1 2 3 4 6 7……这种的,那么可以用(1,4)和(6,2)来表示,这样一来,连续的数都变成了2个数表示。
来了一个新数之后,就用二分法进行查找了。
这样一来,最差情况就是2亿多的断点,也就是2亿多的结构体,每个结构体8个字节,大概16亿字节,1.6GB,在内存中可以放下。
![](https://oscimg.oschina.net/oscnet/22c6be5ac2ff350e8e51091314357aa0f6a.jpg)
吕老师:嗯,非常好,不仅给出了方案,还能主动分析空间和可行性。
小史听完后深感佩服,问题的解决方法绝对不止一种,只要肯动脑筋,即使没有学过bitmap算法,也能有别的方法来解决问题。
【课后】
下课后,小史又找到吕老师。
![](https://oscimg.oschina.net/oscnet/cc7a22d4e931a6113b17e53439e205d1cb8.jpg)
![](https://oscimg.oschina.net/oscnet/5634029aba92dcc33874be3b87e7ec84250.jpg)
吕老师:但是你的理解能力还是很强的,很多东西一听就懂,这可不是谁都能做到的。
相关文章推荐
- 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
- 腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
- 哈希变形—位图(给定40亿个不重复的无符号数整数,没排过序,给一个无符号整数,如何快速判断一个数是否在这40亿个数中)
- 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
- 面试题:给40亿个不重复的无符号整数,没排过序,给一个无符号整数如何快速判断这个数是否在这40亿个数中
- 腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
- 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
- 腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
- 腾讯面试题 腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
- 整数的二进制数中1的数目,1-N中1的总共个数,如何判断一个数是否为2的整数次幂.
- C#实现如何判断一个字符串是否为整数和浮点
- 浮点数在intel上的二进制存储结构,以及如何判断一个浮点数是否为整数
- 浮点数在intel上的二进制存储结构,以及如何判断一个浮点数是否为整数
- 如何判断一个整数数组中是否有重复元素
- 如何判断一个整数数组中是否有重复元素?要求时间复杂度O(n),空间复杂度O(1)
- 如何判断一个整数数组中是否有重复元素?要求时间复杂度O(n),空间复杂度O(1)
- 如何判断一个整数数组中是否有重复元素?要求时间复杂度O(n),空间复杂度O(1)
- java 如何判断一个数是否为2的整数次幂
- 如何在Shell中判断一个变量是否为整数
- 如何判断一个整数数组中是否有重复元素