邏輯題三

一.

15個瓶子,其中最多有一瓶有毒,現在有四只老鼠,喝了有毒的水之后,第二天就會死。如何在第二天就可以判斷出哪個瓶子有毒。

解答:

四只老鼠,用二進制可以給瓶子編碼0001 - 1111

具體操作:


image.png

這里我們將水瓶依次編號為1 - 15, 老鼠依次編號為1 - 4;每只老鼠分別喝下對應二進制位為1的水,最后根據老鼠的死亡情況,可以定位到哪一瓶水有毒。

比如說老鼠3老鼠4都死了,就證明是第3瓶水有毒。

二.

六個海盜搶到共計100個寶石,現在由第一個海盜開始輪流提出分贓計劃,只要同意計劃的人不超過一半,提出計劃的海盜會被處死,然后下個人繼續提出計劃。如果海盜無法獲得認可的最大利益,那么一定會投反對。請問第一個海盜如何提出分贓計劃,保證自己的利益最大化并且不死?

解:逆向推導題目:以最小的支出爭取可以爭取的人。

2人:                   【0 - 100】
3人:                【99 - 1 - 0】
4人:          【97 - 0 - 2 - 1】
5人:     【97 - 0 - 1 - 0 - 2】
6人:【96 - 0 - 1 - 2 - 1 - 0】
  • 當只剩下2個海盜,海盜1海盜2,由海盜1來提出分贓計劃,海盜1只能是自己得0個金幣海盜2分得100金幣,這樣才能保證自己不會被處死。

  • 當只剩下3個海盜,海盜1海盜2海盜3,由海盜1來提出分贓計劃,海盜1給出的分贓計劃是海盜199金幣,海盜21金幣海盜30金幣,這個計劃海盜1海盜2肯定同意,超過一半,海盜2之所以會同意是因為當只剩下海盜2海盜3的時候,海盜2來提出分贓計劃,海盜2一個金幣都沒有,所以海盜2會同意這個計劃。

  • 當只剩下4個海盜,海盜1、海盜2、海盜3、海盜4,由海盜1來提出分贓計劃,海盜1提出的分贓計劃是海盜197金幣,海盜20金幣,海盜32金幣,海盜41金幣,之所以這么分配是依據只有3個海盜的情況來判斷,對于海盜2來說,如果只有3個海盜,他可以分得99個金幣,所以干脆給他0個金幣海盜3,如果只有3個海盜可以分得1個金幣,所以給他2個金幣海盜2肯定同意,海盜4,如果只有3個海盜可以分得0個金幣,所以給他1個金幣,他也會同意。這樣就會超過一半的人同意這個方案。

  • 當只剩下5個海盜,海盜1提出的分贓計劃是海盜197個金幣,海盜20個金幣,海盜31個金幣海盜40個金幣海盜52個金幣,這樣就能保證超過一半的人同意這個計劃。

  • 當只剩下6個海盜時,海盜1提出的分贓計劃是海盜196個金幣,海盜20個金幣,海盜31個金幣海盜42個金幣海盜51個金幣,這樣就能保證超過一半的人同意這個計劃。

三.

100個人搶紅包,每6個人可以成組領取共計3元紅包,每個人限領3次,請問100個人最多可以領取多少錢?

解:
首先100個人中找出4個人,稱作A4,其余96人組成16組領取紅包。接著從96個人中找出4個,稱作B4A4和另外92個人組成16組領取紅包。再從剩下92個人里面找出4人稱作C4A4+B4+88人組成16組領取。最后剩下領取了兩次的A4、B4、C4一起組成兩組,領取紅包,每個人都領取三次,共計領取150

四.

假設有10GB的訂單數據,我們希望按照訂單金額(假設金額都是正整數)進行排序,但是內存有限只有100M,沒辦法一次性將10GB的數據都加載到內存中,請問要怎么進行排序。

解:

  • 先將10GB的數據,分成100份,每份100M,然后分段加載進內存,遍歷統計訂單金額所在范圍,假設統計范圍為0 - 10萬之間,我們將所有的訂單依據訂單金額劃分為100個桶,第一個桶的金額為0 - 1000元, 第二個桶是1001 - 2000元,以此類推,每個桶對應一個存儲文件,并且按照金額范圍大小順序編號命名(00, 01, 02, ... 99);

  • 然后再次分段遍歷10GB的訂單數據,將依據訂單金額,將訂單放入對應的桶中,然后存儲到相應的磁盤上,如果訂單金額分布比較均勻,那每個桶最終的訂單大小差不多是100M左右,但也可能出現相差較大的現象,那就將桶中訂單數據大小超過100M的繼續在該桶金額范圍內繼續劃分,直到每個桶的訂單數據大小,小于100M

  • 然后依次加載每個桶的訂單數據,依據訂單金額,對數據從小到大進行排序。

五.

在一個文件中有 10G個整數,亂序排列,要求找出中位數。內存限制為 2G。只寫出思路即可(內存限制為2G的意思就是,可以使用2G的空間來運行程序,而不考慮這臺機器上的其他軟件的占用內存)。

解:
思路: 一個整數占4個字節,每個字節是8位,將整形的每1位作為一個關鍵字,如果最高位值越大,整數越大,如果最高位相同再比較次高位。整個比較過程類似于字符串的字典排序。

  • 10G整數分成5次,每次2G讀入內存,然后遍歷讀入內存的數據,對每個數據利用位運算取出最高的8位(24 - 31),這8bit最多可以表示255個桶,因此依據最高8bit的值,將整數放入對應的桶中。最后把每個桶寫入磁盤中,同時在統計每個桶中的整數數量,并存儲。

  • 依據內存中統計的每個桶的整數數量,計算中位數在哪個桶中,然后對這個桶進行排序,取出中位數的值。

  • 如果中位數所處的桶的大小超過2G,那么就對這個桶里面的數據依據次高8位繼續進行劃分(16- 23),并統計各個桶中的數量,然后依據之前算成來的桶的數量進行計算,算成中位數處于哪個桶,并對該桶進行排序,取出中位數。

六.

假設我們有 10 萬條 URL 訪問日志,如何按照訪問次數給 URL 排序?

解:

  • 遍歷10萬條數據,以URL作為Key,訪問次數作為Value,存入散列表,同時記錄下訪問次數的最大值k,時間復雜度O(N);

  • 如果K不是很大,可以使用桶排序,時間復雜度是O(N),如果K非常大,就使用快速排序,時間復雜度為O(nlogn);

七.

有兩個字符串數組,每個數組大約有10萬條字符串,如何快速找出兩個數組中相同的字符串。

  • 以第一個字符串數組構建HashSetkey為字符串,再遍歷第二個字符串數組,以字符串為keyHashSet查找,如果包含就說明存在與該字符相同的字符串,添加到相同列表里面。

八.

假設獵聘網有 10 萬名獵頭,每個獵頭都可以通過做任務(比如發布職位)來積累積分,然后通過積分來下載簡歷。假設你是獵聘網的一名工程師,如何在內存中存儲這10萬個獵頭ID和積分信息,讓它支持如下操作:

  • 根據獵頭的ID快速查找、刪除、更新這個獵頭的積分信息。

  • 查找積分在某個區間的獵頭ID列表;

  • 查找按照積分從小到大排名在第x位第y位之間的獵頭ID列表。

解:

  • 獵頭ID構建一個散列表,以積分排序構建一個跳表

  • ID在散列表中所以可以O(1)查找到這個獵頭

  • 積分跳表存儲,跳表支持區間查詢

九.

區塊鏈使用的是哪種哈希算法嗎?是為了解決什么問題而使用的呢?

解:

  • 區塊鏈是一塊塊區塊組成的,每個區塊分為兩部分:區塊頭區塊體

  • 區塊頭保存著自己的區塊體和上一個區塊頭哈希值

  • 因為這種鏈式關系和哈希值的唯一性,只要區塊鏈上任意一個區塊被修改過,后面所有區塊保存的哈希值就不對了。

  • 區塊鏈使用的是SHA256哈希算法,計算哈希值非常耗時,如果要篡改一個區塊,就必須重新計算后面所有區塊的哈希值,短時間幾乎不可能做到。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。