《演算法設計手冊》面試題解答 第二章 演算法分析

2021-09-06 11:40:10 字數 3733 閱讀 9310

簡介:

《演算法設計手冊》(the algorithm design manual)課後面試題和解答。包括:未知大小的集合選取k個元素、資料備份方案、尋找陣列最小數時賦值語句執行次數的期望、100層大樓拋大理石(拋燈泡)、電子秤找不足量金幣、天平找重球、公司合併方案總數、海盜分贓等。

2-43.

從n元集合中取乙個k元子集,並要求每個元素概率相等。若n未知又該如何解決?

解答:原問題在已經解答清楚了。

此文也解決了從未知行數中等概率選擇一行的方法,那麼如果需要選擇k個呢?為了簡化起見,限定未知的n>=k。那麼先選擇前k個元素;對第k+1個元素,以概率k/(k+1)選擇之,並以等概率1/k代替已選擇的k個元素中的乙個。

這樣,這一輪裡前k個元素中某乙個能留下的概率為1/(k+1) + [k/(k+1)] * [(k-1)/k] = k/(k+1)。那麼對於第k+2個元素,類似地,以概率k/(k+2)選擇之,並以等概率1/k代替已選擇的k個元素中的乙個,迴圈直至所有元素遍歷結束。

(解答啟發自

2-44.

有1000份各不相同的資料項和1000個儲存資料的結點,每個結點可以存放3份不同的資料項。制定乙個備份方案,使其在某些結點失效時損失最小。當任意3個結點失效時,丟失的資料的期望數值是多少?

解答:讓所有結點儲存內容不完全相同,是基本的。如果令結點n儲存資料項n、n+1、n+2(取1000的模),最好情況是3個結點失效時不損失資料(各不連續或者2個連續),最壞情況是3個連續結點失效(n、n+1、n+2),損失n+2這乙份資料。這個概率很容易計算,是1/10^(-6)。

raid思想,儲存異或結果,不過我算的概率相同:

類似的處理:

2-45.

從n+1個數中找出最小數時,min = a[i]語句執行次數的期望。其中陣列下標a[0...n]。

(首次賦值min=a[0]計算在內)

解答:首先想到的是逆序對。但是通過序列[1,3,2]和[1,2,3]可知,兩者賦值次數是一樣的,顯然與逆序對無關。

直接從期望入手,記e(n)為n+1個數時的該賦值語句期望執行次數。

最小的數在末尾a[n]的概率為1/n,這時需要一次賦值。

最小的數不在末尾a[n],則末尾處不需賦值,增加的賦值數為0。

這樣,有e(n) = e(n-1) +1/n且e(0)=0。其中e(n-1)已經包括最小的數在非a[n]處的所有情況。因此e(n)為

n比較大時,約為lnn。

(解答來自於:

2-46.

你有一棟100層高的大廈和2塊大理石。你想找出乙個最低樓層,從這個樓層開始,在它和比它更高的樓層上拋下大理石,落地會碎。如果有無限多塊大理石,怎麼最快找出這一層(拋的最少次數)?如果只有兩塊呢?(另一種說法:100層樓扔燈泡)

解答:無限多塊時,很容易想到用折半查詢來進行。但是如果使用最少的大理石塊又該如何找呢?注意到如果某次拋下時大理石未碎,那麼下次仍能夠使用。為了只用兩塊大理石來判斷樓層數,由於碎裂的最低樓層是一定的,先做分析:

假設n是最多需要的測試次數(確定但未知,最壞情況),在第n層扔,如果碎了,由於只剩下乙個燈泡,為了確定1至n-1層中哪一層,最壞情況是從1層一直扔到n-1層,共n-1次,加上之前的1次是n次,不超過n;如果未碎,那麼上到2n-1層再扔,碎時同樣有最壞情況從n+1層扔到2n-2層共n-2次,加上之前的是n次。依次類推,總結出每次測試都是n次,且確定的樓層範圍是:n->2n-1->3n-2->...,即n + (n-1) + ... +1>100。求解使不等式成立的最小正整數是n=14。

(解答來自於:

2-47.

有10袋金幣,其中9袋中每個金幣都是10克,另1袋中每個金幣都是9克。給你乙個能夠數字顯示重量的電子秤,找出全是9克的金幣的那一袋。

解答:看到稱重量可能會聯想到用天平找幾堆商品中不足量的乙份。可是這裡用的是能顯示具體數值的電子秤哎!如果還用天平的思想,可太死板了。

想想權重的概念,解法馬上有了:從1號至10號袋中分別取1至10個金幣,放到電子秤上。如果10袋全是10克的,那麼應該顯示550克;而缺幾克,那就說明那個袋子裡是9克的金幣。一次解決,是不是很簡單?

當然,權重也可以用別的方案分配,不過上面是最簡單的。

(參考自:

2-48.

8個外表一樣的球,其中7個等重,另1個比它們重。用天平在2次的比較後找出這個重球。

解答:由於有「2次比較」的提示,這個就簡單了:把球分為(1,2,3),(4,5,6),(7,8)三組,第一次稱(1,2,3)和(4,5,6),若一組重,那麼將3個中取2個可得重的是這2個之一還是其餘乙個;否則將(7,8)稱重。

如果按這個思路,9個球也能夠解決。

2-49.

將n個公司合併成1個公司,一共有幾種不同的方式合併?

解答:記合併方式f(n)種,f(n)=f(n-1)*g(n),其中g(n)是將n個公司通過一次合併變為n-1個公司的方法。顯然g(n)為組合數c(n,2)。遞推公式解得

(參考自

2-50.

rramanujan數是可以寫作a^3+b^3=c^3+d^3的數,其中a!=c且b!=d,或者a!=d且b!=c。找出滿足所有給定小於n的rramanujan數。

解答:程式設計實現如下

#includeint

main()

}if(int_count == 2

) i++;}}

注意幾點以加速搜尋:

確保j兩個for迴圈終止條件是j^3

(參考自:

2-51.

6個海盜分300美刀,分贓方法如下:有由資歷最深的提出分配方案,進行投票。如果獲得半數及以上支援,那麼按照他的分配方案進行;否則,其他海盜殺掉他,資歷第二深的海盜來提出分配方案,其後仍要投票表決,依次類推。請分析分配方法。(所有海盜都以自己存活為最優考慮,保證存活的條件下才盡可能希望多獲得美刀。)

解答:將海盜按資歷有深到淺編號為1,2,3,4,5,6。假設只剩下5,6兩個海盜時,5無論提出怎樣的分配方案,都能使支援過半(自己的一票),那麼分配方法必然是:

(5,6) ---->(300,0)

時間倒流,加入海盜4。海盜4為了防止投票不過半而被殺死,需要拉攏海盜6。由於6在上一種情況裡什麼也分不到,這時只要4分給6,無論多少,6都會同意。這樣,4給他最少的數目,即1。而5希望進入下一輪投票,因此只有給他全部300刀才能拉攏。由於投票已過半(2/3),不必拉攏5。此時分配方案為:

(4,5,6) ---->(299,0,1)

加入海盜3時,出於類似的考慮,提出這樣的方案:

(3,4,5,6) ---->(299,0,1,0),這樣能拉攏5,不至於3死後,5什麼也分不到。

(299,1,0,0)必然不能拉攏4,因為將3乾掉後4能獲得299。至於為什麼不用(299,0,0,1)這樣的方案呢?此時6無論是否同意,他都有機會在本輪獲得1美刀或者把3乾掉後的下一輪必然獲得1美刀。因此3的倖存與否是未知的,他不能做出這種使自己生命可能受到威脅的分配方式。後面的分析類似。有:

(2,3,4,5,6) --->(298,0,1,0,1)

(1,2,3,4,5,6) ----> (298,0,1,0,1,0)

(參考自:這裡我補充了不少分析。)

2.52.

如果2.51中只有1美刀來分贓,誰會得到它,在這個分配過程中會死多少人?

解答:和上一題分析類似,當只有2個海盜時,年長那個一定能得到那1美刀;當海盜數大於等於3時,任何分配給自己的分配方案都不能保證自己一定能存活,不如直接分給倒數第二個海盜。(但即使如此,也可能被殺死。投票將演化成殺死一部分海盜,然後讓倒數第二個海盜獲得的過程。)

(更一般的情況請參考注意,中文wiki上沒有詳細的擴充套件情況的介紹。)

Python面試題解答 第二部分企業面試題

企業面試題 a.在python裡凡是繼承了object的類,都是新式類 b.python3裡只有新式類 c.python2裡面繼承object的是新式類,沒有寫父類的是經典類 d.經典類目前在python裡基本沒有應用 e.保持class與type的統一對新式類的例項執行a.class 與type ...

第二章面試題2 實現單例模式

什麼是單例模式 singleton 保證乙個類只有乙個例項,且提供乙個訪問它的全域性訪問點 為什麼需要單例模式 有一些類只需要使用乙個例項,如工具箱等 需要實現對唯一例項的受控訪問 怎麼實現單例模式 要求 判斷物件是否被例項化,若例項化了則直接使用例項 是否例項化應該由該類自己判斷,不需要客戶判斷,...

網路作業系統第二章課後習題解答

1.windows server 2008 中的使用者有哪些型別?系統預設的使用者有哪些?使用者型別 1 使用者 2 inetorgperson 3 聯絡人 4 預設使用者賬戶。預設使用者 1 administrator 2 guest。2.如何在 windows server 2008 中管理本地...