BitMap是用bit位来记录数据存在与否的一种算法。在处理大数据时,可以节省大量空间,速度也很快。
先来看一个例子。
已知有n个整数,这些整数的范围是[0,100],请你设计一种数据结构,使用数组存储这些数据,并提供两种方法,
分别是addMember和isExist.下面是这种数据结构的类的定义。
function FindClass(){
var datas = [];//存储数据
//加入一个整数
this.addMember = function(member){
//TODO
}
// 判断member是否存在
this.isExist = function(member){
//TODO
}
}
//测试用例
var fc = new FindClass();
var arr = [0,3,5,6,9,34,23,78,99];
for (let i = 0; i < arr.length; i++) {
fc.addMember(arr[i])
}
console.log(fc.isExist(3));
console.log(fc.isExist(7));
console.log(fc.isExist(78));
当实现addMember和isExist之后,执行上面的代码,预期输出的结果是:
true
false
true
实现方式 一
//实现方式 一
this.addMember = function(member){
datas.push(member)
}
this.isExist = function(member){
for (let i = 0; i < datas.length; i++) {
if(datas[i]==member){
return true;
}
}
return false;
}
//isExist 的实现方式2
this.isExist = function(member){
if(datas.indexOf(member)>=0){
return true;
}
return false;
}
实现方式 二
方式一虽然实现了功能,但是速度慢,不论使用for循环还是indexOf的方法,时间复杂度都是O(n),加入的元素越多,isExist方法的速度越慢, 我们需要一个时间复杂度是O(1)的算法,不论向里面增加了多少数据,isExist的执行速度都是常量时间。
通过索引操作数据,时间复杂度就是O(1)。题目说明这些数在0-100之间,那么就用每个数自身的值作为索引,比如3这个数,可以让data[3]=1, 就表示把3添加进来了。data[2]=0,表示2没有添加进来,如此,isExist方法就可以利用索引来判断member是否存在。
function FindClass(){
var datas = new Array(100);
//先都初始化为0
for (let i = 0; i < datas.length; i++) {
datas[i] = 0;;
}
//添加一个整数
this.addMember = function(member){
datas[i] = 1;
}
//判断member是否存在
this.isExist = function(member){
if(datas[member]==1){
return true;
}else{
return false;
}
}
}
更节省空间的算法
上面的算法已经很快了。但是却面临一个新的问题,如果数据非常多,多达1亿,每个整数是4