判读40亿数字中是否有某个数字

  网上大部分是使用的bitmap算法。大体思路是:一个字节(Byte) 在计算机中占8位(bit),每个位(bit)可以表示一个数字,1表示含有,0表示不含有。1个32位系统的int类型可以存储2的32次方个bit位,大约是42亿多点。这样40亿需要 40/8=5亿字节,1M =1024KB*1024=1042576Byte,故大概需要512M左右大小即可。空间复杂度是O(n)+O(1);

还有更好的方法:

这个问题在《编程珠玑》里有很好的描述,大家可以参考下面的思路,探讨一下:
又因为2^32为40亿多,所以给定一个数可能在,也可能不在其中;
这里我们把40亿个数中的每一个用32位的二进制来表示
假设这40亿个数开始放在一个文件中。

然后将这40亿个数分成两类:
      1.最高位为0
      2.最高位为1
    并将这两类分别写入到两个文件中,其中一个文件中数的个数<=20亿,而另一个>=20亿(这相当于折半了);
与要查找的数的最高位比较并接着进入相应的文件再查找

再然后把这个文件为又分成两类:
      1.次最高位为0
      2.次最高位为1

并将这两类分别写入到两个文件中,其中一个文件中数的个数<=10亿,而另一个>=10亿(这相当于折半了);
    与要查找的数的次最高位比较并接着进入相应的文件再查找。
    .......
    以此类推,就可以找到了,而且时间复杂度为O(logn)

原文地址:https://www.cnblogs.com/thinkingandworkinghard/p/9545917.html

时间: 2024-10-05 12:22:23

判读40亿数字中是否有某个数字的相关文章

如何从40亿整数中找到不存在的一个

前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况下,如何解决该问题?如果有几个外部的"临时"文件可用,但是仅有几百字节的内存,又该如何解决该问题? 分析 这仍然是<编程珠玑>中的一个问题.前面我们曾经提到过<位图法>,我们使用位图法解决了这个问题.32位整型最多有4294967296个整数,而很显然40亿个数中必然会至少缺一个.我们同样也可以尝试使

给40亿个不重复的unsigned int的数,没排序,然后再给一个数,如何快速间断这个数是否在那40亿个数中

40亿个数,如果用无符号的long long数组来存,那么使用数组里的每一个元素的每一位代表一个数,具体为: a[0]  ---- 0~63 a[1]  ---- 64~127 a[2]  ---- 128~190 ... 那么,40亿 bit/64 = 6.25*107 *8 byte = 500MB , 内存就满足了. #include <iostream> #include <bitset> #include <cstring> #include <vect

从40亿个整数中找到不存在的一个

前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况下,如何解决该问题?如果有几个外部的"临时"文件可用,但是仅有几百字节的内存,又该如何解决该问题? 分析 这仍然是<编程珠玑>中的一个问题.前面我们曾经提到过<位图法>,我们使用位图法解决了这个问题.32位整型最多有4294967296个整数,而很显然40亿个数中必然会至少缺一个.我们同样也可以尝试使

【面试被虐】如何只用2GB内存从20亿,40亿,80亿个整数中找到出现次数最多的数?

这几天小秋去面试了,不过最近小秋学习了不少和位算法相关文章,例如 [面试现场]如何判断一个数是否在40亿个整数中? [算法技巧]位运算装逼指南 对于算法题还是有点信心的,,,,于是,发现了如下对话. 20亿级别 面试官:如果我给你 2GB 的内存,并且给你 20 亿个 int 型整数,让你来找出次数出现最多的数,你会怎么做? 小秋:(嗯?怎么感觉和之前的那道判断一个数是否出现在这 40 亿个整数中有点一样?可是,如果还是采用 bitmap 算法的话,好像无法统计一个数出现的次数,只能判断一个数是

剑指Offer对答如流系列 - 圆圈中最后剩下的数字

面试题62:圆圈中最后剩下的数字 题目描述 0, 1, -, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,从数字0开始每次删除第3个数字,则删除的前四个数字是2 0 4 1 因此最后剩下的数字是3 问题分析 思路一: 既然涉及到数据的频繁删除,可以考虑使用链表来存放数据,每次对长度取余数可以实现循环操作. 思路二: 这种问题规律性非常强,其实已经有对这一规律背后的数学模型的探究,即约瑟夫环 举一个具体的场景: 据说著名犹太历

9.10扩展性与存储限制(二)——给定一个输入文件,包含40亿个非负整数。产生一个不在该文件中的整数。内存限制:1GB

/** * 功能:给定一个输入文件,包含40亿个非负整数.产生一个不在该文件中的整数.内存限制:1GB * 进阶:内存限制10MB. */ /** * 思路: * * 1)创建包含40个亿个比特的位向量. * 位向量(BV,bit vector)其实就是数组,利用整数(或另一种数据类型)数组紧凑地储存布尔值.每个整数可存储一串32比特或布尔值. * 2)将BV的所有元素初始化为0. * 3)扫描文件中的所有数字(num),并调用BV.set(num,1). * 4)接着,再次从索引0开始扫描BV

剑指offer——面试题40:数组中只出现一次的数字

题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: (1)首先考虑数组中若是只有一个数字是出现一次,其他都是出现两次的情况,在这种情况下,将所有的 数字都位异或运算(^),因为相同的数字异或结果为0,所以最后地到的结果就是那个出现一次的数. (2)下面考虑本题出现有两个出现一次,其他的都是出现一次,这种情况下,可以将所有的异或一遍, 那么最后得到的结果为这两个出现一次的数的异或的结果. 然后找到这个数的从右为0数起的第一个不为0的位,这样

6.3 40亿个非负整数中找到没出现的数

[题目]: 32位无符号整数的范围是0~4294967295,现在有一个正好包含40亿个无符号整数的文件,所以在整个范围中必然有没出现过的数.可以使用最多1GB的内存,怎么找到所有没出现过的数 [进阶]: 内存限制为10MB,但是只用找到一个没出现过的数即可 原文地址:https://www.cnblogs.com/latup/p/9942103.html

【剑指offer】面试题40:数组中只出现一次的数字

题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 因为只有两个只出现一次的数字,所以所有数字进行异或之后得到值res一定不是0.这样,res中其中至少1bit不是0,我们根据这个bit是否为0把数组分为两组,两个只出现一次的数字肯定在不同的组.其他出现两次的数组两个肯定在相同组,而两个相同的数组异或之后是0,任意一个数字与0异或还是该数字本身. 代码: class Solution { public: void FindNumsAppe