測試雞蛋的硬度:一道關於查找的面試題

一道關於查找的面試題。

當時有點思維定式,懵逼的狀態,沒有解答好。


題目是這樣的:

  背景:在你面前有一棟樓,總高200層,你手裏有兩個雞蛋,並且兩個雞蛋的硬度相同,並且雞蛋的硬度通過從某層樓上落下是否摔碎來定義,假設雞蛋從20樓落下沒有碎,但是從21樓落下碎了,那麼就認爲雞蛋的硬度是20。

 那麼問題來了:利用你手裏僅有的兩個雞蛋和你面前的這棟樓,準確測試除雞蛋的硬度,要求考慮到測試過程的效率。


從算法的角度分析,這個情景其實是要寫一個對有序序列的查找算法。


當時思維定式,一直想着二分查找法,那麼如果第一次從100層丟下一個雞蛋恰好碎了,那麼就只能老老實實從1樓一層一層往上爬...,時間複雜度就不是log_n而會變成n/2,因爲最多隻有2次試探的機會。顯然性能是很差的。


然後思考的各種思路都被這種定勢的思維侷限,在面試的那5分鐘之內都沒有想到好的方法。


然而昨晚躺牀上睡不着,和室(基)友促膝長談,一番討論被點撥了一下,突然就靈光乍現了。所以說果然當你的思維陷入一個定勢的怪圈,還是需要有人能拉你一把的。


因爲只有兩個雞蛋,用二分的試探性查找很顯然是不太可取的,極端情況下性能會非常差。

那麼不用二分,用m分呢?

假設我先從10樓丟下一個雞蛋,如果碎了,就用剩下的一個雞蛋從一樓一層層往上找;如果10樓丟下沒碎,那麼再嘗試20樓,碎了的話就從11樓開始一層層往上找。

這種方法是可行的,並且如果m值選取得當,最壞情況的時間複雜對會比二分情況下的時間複雜度低得多。

不妨列一個簡單的式子,找出最恰當的m值。

考慮最壞的情況:

需要查找(丟雞蛋)的次數爲

               O(n)=n/m+m;

在上面的例子中,n的取值爲200,我們需要通過這個式子求出當O(n)最小時,m的取值。

它的圖像在第一象限(m必須是大於零的)是一個類似於“√”的形狀,有一個最小值,那麼可以對這個式子求導數,當倒數爲零的時候,m的取值會使O(n)最小,即

               0=-n/m^2+1;

得到m取值應該爲√n,所以也就得出當m取值爲√n時,該情景的查找時間複雜度爲2√n。


這是目前我想到的最優的算法,不知道是否還有更優的算法呢,期待有研究的大神不吝賜教。




發佈了33 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章