[面试题] BloomFilter 无序40亿不重复 uint 整数, 给予任意的数,求是否在这40亿之中 + 无序数组中找2个相同的值

一道百度面试题(待解中)

具体:给40亿个不重复的unsigned int的整数,没排过序的,然后再给几个数,如何快速判断这几个数是否在那40亿个数当中?

分析下,首先应该是空间复杂度(40亿uint = 400000000*4 byte = 15258 MB 差不多16G), 再试时间复杂度

因为是无序的,所以 不能用B树索引,B+ 树索引 ( 默认数据库中 索引会用, 因为有序,所以支持 上一个,下一个)

网上普遍应该是
1.40亿数据 分片
2.结果放到bit中,然后查找bitset 判断是否存在

其实应该是:

1.散列分治

hash for bitset

  • std::hash

unordered_set

hash

2.看到一些大数据的书之后,了解到 布隆过滤器

布隆过滤器 Bloom filter 是由Howard Bloom在1970年提出的 二进制向量 数据结构,它具有很好的空间和时间效率,尤其是空间效率,BF常常被用来检测某个元素 是否是 巨量数据集合中的 成员。

基本原理: 使用m的位数组(bitset 或者 bit a[])来存储集合信息, 使用k个相互独立的hash函数 将数据映射到位数组空间(hash函数独立,所以可以是 分布式机器 + 多线程 + 多进程 操作)

假设 位数组bit arrayA[m], 函数函数(1~k),40亿不重复的uint 为集合S, S中某成员a(假如值是123)
arrayA 中所有元素 默认置0,对于 a进行hash

40亿hash 之后,

2^32 =42亿左右

所以,用bitset<2^32> 每个bit位 代表每个unsigned int数值,是否存在。
使用hash开放寻址法, 比如 100,2000,5000,80000, 这几个数值的第100位,第2000位,第5000位,第80000位 都是1。


// bitset::operator[]
#include <iostream>       // std::cout
#include <bitset>         // std::bitset

int main ()
{
  std::bitset<2^32> foo;

  foo[100]=1;            
  foo[2000]=1;
  foo[5000]=1;
  foo[80000]=1;

  std::cout << "foo: " << foo << '\n';

  return 0;
}


[tt面试题] 一维数组 a[100],里面的值为1~999,里面有2个值一样,

求怎么样 以最快的时间复杂度,和空间复杂度,找到这个值,

后记:添加, 采用 hash(链接方式),

   创建一个 key[999]的数组,把值当做index ,

   a中各个值, 放入到key中,   

    比如a[10] = 88

    那么key[88] =   a[10]的信息,比如10, 这个可以是一个链表,  如果a[10], a[12] 值都是 88,那么用双向链表, 保存 a[10] ,a[12]的信息。

时间复杂度是O(n)
空间复杂度是O(m)//m 是数组中值 的取值范围

参考HASH 的 链接法(chaining)

当让 空间足够的话,可以采用桶排序 时间复杂度是O(1),空间复杂度是O(999)

用上面的BF是 最好的,空间复杂度,时间复杂度, 都是最小。

posted @ 2015-06-17 22:53  scott_h  阅读(809)  评论(0编辑  收藏  举报