[面试题] 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.散列分治
- 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是 最好的,空间复杂度,时间复杂度, 都是最小。