摔雞蛋問題與跳表

2022-01-24 08:00:55 字數 1645 閱讀 4355

摔雞蛋問題:給你k個雞蛋,讓你測試雞蛋殼的硬度,測量的方法就是從不同高度的樓層向下扔,如果雞蛋在第i層摔碎了而在第i-1層沒摔碎,那麼我們就知道雞蛋殼的硬度了,即用層數代表雞蛋殼的硬度。並且假設雞蛋肯定能用某一層的層數來表示。現在的問題是,用k個雞蛋,最壞情況下最少需要多少次才能測試出雞蛋殼的硬度?

例如只有乙個雞蛋,那麼為了保證在測出雞蛋殼硬度之前雞蛋不破裂,只能一層一層的試。如果樓的高度有n層,那麼最查情況需要n次實驗。

如果有兩個雞蛋呢?假設最壞情況最少需要m次實驗,那麼第一只雞蛋只能最多在第m層進行實驗,如果第m層沒有摔碎,那麼接下來就必須在第m+m-1層進行實驗,如果第m層摔碎了,那麼第二隻雞蛋就必須從第1層到第m-1層逐層進行實驗,這樣能保證最壞情況下至多實驗m次。依次類推,那麼我們求得乙個實驗的樓層間隔序列m, m-1, m-2,...... 1,這樣能保證m最小,那麼也就是說m取1+2+......+m>=n的最小值。

對於任意數量的雞蛋和任意高度的樓層並沒有乙個直接的公式能夠計算出最壞情況最少需要多少次實驗,實際上這是乙個動態規劃問題。

那麼,什麼是跳表?這和跳表有什麼關係呢?

假如我們要儲存n個字串,字串的長度不一,我們如何能夠高效率的儲存這些字串呢?如果我們給每個字串分配同樣大小的記憶體,那麼每個字串開銷和最長的字串開銷一樣,這樣必然會極度浪費空間。但是這樣儲存的好處是可以很快的進行字串查詢,例如可以用二分查詢。

現在我們要做到,既要儲存上不浪費空間,而且查詢效率也要能夠很好,怎麼辦?字典樹,平衡二叉樹?這些都可以,但是要儲存這種樹結構又不免的浪費一些空間,而且實現上比較複雜。這裡面就要用到跳表了。

要使得儲存高效,那麼最簡單的辦法就是字串有多長,就給其分配那麼大的空間,不需要大小固定一致,並且每個字串前用固定幾個位元組儲存其長度,這樣就可以很方便的從儲存的開始處識別出每個字串。那麼問題來了,這樣做不能得到很好的查詢效率,因為二分的方法在這裡面無用武之地。跳表的思想就是,在這個字串序列之間插入一定數量的指標,使得查詢時不是僅僅查詢後面相鄰的字串,而是跳過一定數量的字串。

如圖在第乙個表中查詢f需要6次查詢,而在第二個表中只需5次。那麼現在的問題是,如果字串的數目是n個,我們需要多少個跳躍指標?每個指標之間的間隔又是多少呢?

假設這裡如果你不在乎額外的儲存指標的空間開銷,那麼可以用n個指標,每個指標指向乙個字串,而且這樣可以利用二分查詢,在很多規模不算太大的問題當中,這種方法相當的好。

但是如果你覺得儲存指標都很浪費空間,那麼就需要跳表了。這個和摔雞蛋問題是一樣的,沒有乙個公式能夠告訴你應該怎麼做才是最優的。實際上最常用的策略就是等間隔插入指標,並且效果不錯。

假設表長度為n,需要等間隔插入k個指標,那麼最差情況下需要k+n/k次查詢來查詢乙個元素,即y=k+n/k,對k求導,y'=1-n/k2,讓y'=0求得y取最小值時k的值,1-n/k2=0 => k2 = n => k=sqrt(n),即最優情況下需要sqrt(n)個指標,每個指標的間隔也是sqrt(n)。

例如表長度為100萬,那麼k=1000時,最壞需要1000+1000=2000次查詢來查詢乙個元素,而順次查詢期望是50萬次查詢乙個字串。雖然有很多方法可以解決這種既要求儲存效率高又要求查詢速度也要很好的問題,但是無疑跳表的思想是最簡單的,並且很多實際的問題就是用這種方法解決的。總之一句話,簡單就是美。

摔雞蛋問題

扔雞蛋問題 原題描述 兩個軟硬程度一樣但未知的雞蛋,它們有可能都在一樓就摔碎,也可能從一百層樓摔下來沒事。有座100層的建築,要你用這兩個雞蛋通過最少的次數確定哪一層是雞蛋可以安全落下的最高位置。可以摔碎兩個雞蛋 方法分析 看到這個題目,最保險的方法就是一層一層試驗,但這樣只需要乙個雞蛋就可以了。我...

100層樓摔雞蛋問題

reference 題目 有一棟100層高樓,從某一層開始扔下的玻璃杯剛好摔壞,現有兩個玻璃杯,最少幾次能找到那一層?首先我要對題目的表述提點意見。這是乙個很有歧義的表述方式,容易誤導人向概率的方向去思考。比如說,我可以回答 最少一次能找到那一層 我就拿個杯子,從一樓起一層一層的摔。從概率上講,有可...

N個雞蛋從M樓層摔(2個雞蛋從100層摔)

一 題目 有一棟樓共100層,乙個雞蛋從第n層及以上的樓層落下來會摔破,在第n層以下的樓層落下不會摔破。給你2個雞蛋,設計方案找出n,並且保證在最壞情況下,最小化雞蛋下落的次數。二 思路 先假設,最小的次數為x次。首先在x層摔,那麼會出現兩個結果 1 碎了,為了找出那一層碎了,第二個雞蛋必須從1 x...