如果给你40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中?
- 遍历,时间复杂度O(N)
- 排序(O(NlogN)),利用二分查找: logN
- 位图解决 数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。比如:
1.位图的概念
所谓位图,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是 用来判断某个数据存不存在的。
2.位图的实现
位图这种结构相对于前面的二叉搜索树哈希来说是十分简单的,这里我们二话不说,直接看实现代码:
#pragma once
#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;
class BitSet
{
public:
BitSet(size_t range)
{
_bits.resize((range >> 5) + 1, 0); //range 位图的空间大小单位:比特,右移动5转化为int大小,进行初始化,每位初始化为0
}
void Set(size_t x) //置1操作
{
size_t index = x >> 5; //计算x在位图中第几个(int)元素中
size_t num = x % 32; //计算x对应该int的四个字节中的哪一位?
_bits[index] |= (1 << num); //将x对应的比特位置为1
}
void Rest(size_t x) //置0操作
{
//x位置的计算
size_t index = x >> 5;
size_t num = x % 32;
_bits[index] &= ~(1 << num); //将x对应位置的比特位的值置为0
}
bool Test(size_t x) //判断x是否存在
{
//计算位置
size_t index = x >> 5;
size_t num = x % 32;
return _bits[index] & (1 << num);
}
private:
std::vector<int> _bits;
};
3.位图的应用
1. 快速查找某个数据是否在一个集合中
2. 排序
3. 求两个集合的交集、并集等
4. 操作系统中磁盘块标记