使用bit-map可以解决的题

来自于《编程珠玑》。所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素。由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省。

如果说了这么多还没明白什么是Bit-map,那么我们来看一个具体的例子,假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复)。那么我们就可以采用Bit-map的方法来达到排序的目的。要表示8个数,我们就只需要8个Bit(1Bytes),首先我们开辟1Byte的空间,将这些空间的所有Bit位都置为0,然后遍历这5个元素,首先第一个元素是4,那么就把4对应的位置为1(可以这样操作 p+(i/8)|(0×01<<(i%8)) 当然了这里的操作涉及到Big-ending和Little-ending的情况,这里默认为Big-ending),因为是从零开始的,所以要把第五位置为1。然后再处理第二个元素7,将第八位置为1,,接着再处理第三个元素,一直到最后处理完所有的元素,将相应的位置为1。然后我们现在遍历一遍Bit区域,将该位是一的位的编号输出(2,3,4,5,7),这样就达到了排序的目的。

下面是几道腾讯笔试题:

一、两个整数集合A和B,求其交集

1、读取整数集合A中的整数,将读到的整数插入到map中,并将对应的值设为1.

2、读取整数集合B中的整数,如果该整数在map中并且值为1,则将此数加入到交集当中,并将在map中的对应值改为2.

通过更改map中的值,避免了将同样的值输出两次。

二、找出1到10w中没有出现的两个数字

有1到10w这10w个数,去除2个数并打乱次序,如何找出那两个数?

想法一:申请10w个bit的空间,每个bit代表一个数字是否出现过。

开始时,将这10w个bit都初始化为0,表示所有数字都没有出现过。

然后依次读入已经乱序的数字,并将对应的bit设为1.

当处理完所有书之后,根据为0的bit得出没有出现的数字。

想法二:首先计算1到10w的和、平方和

       然后计算给定数字的和、平方和

两次得到的数字相减,可以得到这两个数字的和、平方和

有:x + y = n

       x^2 + y^2 = m

解方程可以得到x、y的值。

三、有1000瓶水,其中有一瓶有毒,小白鼠只要尝一点带毒的水,24小时候就会死亡,至少要多少只小白鼠才能在24小时时鉴别出哪瓶水有毒?

将1000瓶水编号。准备10只小白鼠并编号2^10=1024,用二进制表示为10000000000,一共有11位,因为1024>1000,所以1000瓶水分别可以抽象表示为10位二进制数。将10只小白鼠分别对应每一 让小白鼠按位去喝药水(遇见1喝,遇见0不喝)      

类似下图:

如果小白鼠A、B、C都没死(000),则编号为0的水瓶中的水有剧毒;
如果小白鼠A、B没死,C死(001),则编号为1的水瓶中的水有剧毒;
如果小白鼠A、C没死,B死(010),则编号为2的水瓶中的水有剧毒;
如果小白鼠A没死,B、C死(011),则编号为3的水瓶中的水有剧毒;
如果小白鼠A死,B、C没死(100),则编号为4的水瓶中的水有剧毒;
如果小白鼠A、C死,B没死(101),则编号为5的水瓶中的水有剧毒;
(实质上:我们可以保持小白鼠的位置不变,给没死的小白鼠贴上标签0,死的贴上标签1,会得出一串二进制码,在将此段二进制码转换成为十进制,即得出有剧毒水瓶的编号)

四、判断数字是否出现在40亿个书中

给40亿个不重复的unsigned int 的整数,无序,如何查找一个数是否在那40亿个数当中

情况一:内存足够

unsigned int的取值范围是0到2^32-1。我们可以申请连续的2^32/8 = 512M,用每一个bit对应一个unsigned int数字。首先将512M内存都初始化为0,然后每处理一个数字就将其对应的bit设置为1。当需要查询时,直接找到对应bit,看其值是0还是1。

情况二:内存不足

使用二分搜索,每次将范围限定在数量较少的那一半空间中,这样顶多 logN 次搜索之后就可以限定所求整数(N为整数个数)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章