使用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爲整數個數)。

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