1. 程式人生 > >[面試題] 隨機數相關面試題(1)

[面試題] 隨機數相關面試題(1)

1.谷歌面試題:給定能隨機生成整數15的函式,寫出能隨機生成整數17的函式。

此題的關鍵是讓生成的17的數出現概率相同。只要我們可以從n個數中隨機選出1n個數,反覆進行這種運算,直到剩下最後一個數即可。

我們可以呼叫n次給定函式,生成n15之間的隨機數,選取最大數所在位置即可滿足以上要求。

例如,初始的7個數[1,2,3,4,5,6,7]715的隨機數[5,3,1,4,2,5,5],那麼我們保留下[1,6,7],   315的隨機數[2,4,1],那麼我們保留下[6]6就是我們這次生成的隨機數。

2.谷歌面試題:判斷一個自然數是否是某個數的平方。當然不能使用開方運算。

假設待判斷的數字是N

方法1

遍歷從1N的數字,求取平方並和N進行比較。如果平方小於N,則繼續遍歷;如果等於N,則成功退出;如果大於N,則失敗退出。複雜度為O(n^0.5)

方法2

使用二分查詢法,對1N之間的數字進行判斷。複雜度為O(logn)

方法3

由於   (n+1)^2= n^2+2n+1   = ... = 1+(2*1+1)+(2*2+1)+...+(2*n+1) ,注意到這些項構成了等差數列(每項之間相差2)。所以我們可以比較N-1N-1-3N-1-3-5...0的關係。如果大於0,則繼續減;如果等於0,則成功退出;如果小於0,則失敗退出。複雜度為O(n^0.5)

不過方法3中利用加減法替換掉了方法1中的乘法,所以速度會更快些。

3.谷歌面試題:給定一個數據流,其中包含無窮盡的搜尋關鍵字(比如,人們在谷歌搜尋時不斷輸入的關鍵字)。如何才能從這個無窮盡的流中隨機的選取1000個關鍵字?

定義長度為1000的陣列。對於資料流中的前1000個關鍵字,顯然都要放到陣列中。對於資料流中的的第nn>1000)個關鍵字,我們知道這個關鍵字被隨機選中的概率為1000/n。所以我們以1000/n的概率用這個關鍵字去替換陣列中的隨機一個。這樣就可以保證所有關鍵字都以1000/n的概率被選中。

對於後面的關鍵字都進行這樣的處理,這樣我們就可以保證陣列中總是儲存著1000個隨機關鍵字。

4.谷歌面試題:將下列表達式按照複雜度排序

2^n   n^Googol(其中Googol=10^100)   n!   n^n

按照複雜度從低到高為   n^Googol   2^n   n! n^n

5.谷歌面試題:在半徑為1的圓中隨機選取一點。

假設圓心所在位置為座標元點(0,0)

方法1.

x[-1,1]y[-1,1]的正方形內隨機選取一點。然後判斷此點是否在圓內(通過計算此點到圓心的距離)。如果在圓內,則此點即為所求;如果不在,則重新選取直到找到為止。正方形的面積為4,圓的面積為pi,所以正方形內的隨機點在圓內的概率是pi/4

方法2.

[0,2*pi)中隨機選一個角度,對應於圓中的一條半徑,然後在此半徑上選一個點。但半徑上的點不能均勻選取,選取的概率應該和距圓心的長度成正比,這樣才能保證隨機點在圓內是均勻分佈的。

6.谷歌面試題:給定一個未知長度的整數流,如何隨機選取一個數

方法1.

將整個整數流儲存到一個數組中,然後再隨機選取。如果整數流很長,無法儲存下來,則此方法不能使用。

方法2.

如果整數流在第一個數後結束,則我們必定會選第一個數作為隨機數。如果整數流在第二個數後結束,我們選第二個數的概率為1/2。我們以1/2的概率用第2個數替換前面選的隨機數,得到滿足條件的新隨機數。.... 如果整數流在第n個數後結束,我們選第n個數的概率為1/n。我們以1/n的概率用第n個數替換前面選的隨機數,得到滿足條件的新隨機數。.... 利用這種方法,我們只需儲存一個隨機數,和迄今整數流的長度即可。所以可以處理任意長的整數流。

7.谷歌面試題:設計一個數據結構,其中包含兩個函式,1.插入一個數字,2.獲得中數。並估計時間複雜度。

1.使用陣列儲存。

插入數字時,在O(1)時間內將該數字插入到陣列最後。獲取中數時,在O(n)時間內找到中數。(選陣列的第一個數和其它數比較,並根據比較結果的大小分成兩組,那麼我們可以確定中數在哪組中。然後對那一組按照同樣的方法進一步細分,直到找到中數。)

2.使用排序陣列儲存。

插入數字時,在O(logn)時間內找到要插入的位置,在O(n)時間裡移動元素並將新數字插入到合適的位置。獲得中數時,在O(1)複雜度內找到中數。

3.使用大根堆和小根堆儲存。

使用大根堆儲存較小的一半數字,使用小根堆儲存較大的一半數字。插入數字時,在O(logn)時間內將該數字插入到對應的堆當中,並適當移動根節點以保持兩個堆數字相等(或相差1)。獲取中數時,在O(1)時間內找到中數。

8.谷歌面試題:在一個特殊陣列中進行查詢,給定一個固定長度的陣列,將遞增整數序列寫入這個陣列。當寫到陣列尾部時,返回陣列開始重新寫,並覆蓋先前寫過的數。請在這個特殊陣列中找出給定的整數。

假設陣列為a[0,1,...,N-1]。我們可以採用類似二分查詢的策略。

首先比較a[0]a[N/2],如果a[0]然後判斷要找的整數是否在遞增子序列範圍內。如果在,則使用普通的二分查詢方法繼續查詢;如果不在,則重複上面的查詢過程,直到找到或者失敗為止。

9.谷歌面試題:1024!末尾有多少個0

末尾0的個數取決於乘法中因子25的個數。顯然乘法中因子2的個數大於5的個數,所以我們只需統計因子5的個數。是5的倍數的數有:1024/5=204,  25的倍數的數有:1024/25=40, 125的倍數的數有:1024/125=8, 625的倍數的數有:1024/625=1

所以1024!中總共有204+40+8+1=253個因子5。也就是說1024!末尾有2530