google 面試題第五解 十倍

2021-08-26 17:28:50 字數 1781 閱讀 8741

有一篇文章谷歌面試趣事中提到的面試題。

問題是這樣的:

假設這有乙個各種字母組成的字串,假設這還有另外乙個字串,而且這個字串裡的字母數相對少一些。從演算法是講,什麼方法能最快的查出所有小字串裡的字母在大字串裡都有?

比如,如果是下面兩個字串:

string 1: abcdefghlmnopqrs

string 2: dcgsrqpom

答案是true,所有在string2裡的字母string1也都有。如果是下面兩個字串:

string 1: abcdefghlmnopqrs

string 2: dcgsrqpoz

答案是false,因為第二個字串裡的z字母不在第乙個字串裡。

對於這種操作一種幼稚的做法是輪詢第二個字串裡的每個字母,看它是否同在第乙個字串裡。從演算法上講,這需要o(n*m)次操作,其中n是string1的長度,m是string2的長度。就拿上面的例子來說,最壞的情況下將會有16*8 = 128次操作。

乙個稍微好一點的方案是先對這兩個字串的字母進行排序,然後同時對兩個字串依次輪詢。兩個字串的排序需要(常規情況)o(m log m) + o(n log n)次操作,之後的線性掃瞄需要o(m+n)次操作。同樣拿上面的字串做例子,將會需要16*4 + 8*3 = 88加上對兩個字串線性掃瞄的16 + 8 = 24的操作。(隨著字串長度的增長,你會發現這個演算法的效果會越來越好)

最終,我告訴了他乙個最佳的演算法,只需要o(n+m)次操作。方法就是,對第乙個字串進行輪詢,把其中的每個字母都放入乙個hashtable裡(成本是o(n)或16次操作)。然後輪詢第二個字串,在hashtable裡查詢每個字母,看能否找到。如果找不到,說明沒有匹配成功。這將消耗掉8次操作 —— 這樣兩項操作加起來一共只有24次。不錯吧,比前面兩種方案都要好。

guy沒有被打動。他把他的皮褲子弄的沙沙響作為回應。」還有沒有更好的?「他問道。

我的天?這個傢伙究竟想要什麼?我看看白板,然後轉向他。」沒有了,o(n+m)是你能得到的最好的結果了 —— 我是說,你至少要對每個字母至少訪問一次才能完成這項操作 —— 而這個方案是剛好是對每個字母只訪問一次「。我越想越確信我是對的。

他走到白板前,」如果這樣呢 —— 假設我們有乙個一定個數的字母組成字串 —— 我給每個字母分配乙個素數,從2開始,往後類推。這樣a將會是2,b將會是3,c將會是5,等等。現在我遍歷第乙個字串,把每個字母代表的素數相乘。你最終會得到乙個很大的整數,對吧?然後 —— 輪詢第二個字串,用每個字母除它。如果除的結果有餘數,這說明有不匹配的字母。如果整個過程中沒有餘數,你應該知道它是第乙個字串恰好的子集了。這樣不行嗎?「

我不知道這位老大是怎麼實現素數乘除的,就我來說,實現後效果卻大跌眼鏡。

對於1000000次迴圈,

checkstringinbyhashmap: 203ms

checkstringinbyprime: 3357ms

相差了10倍, 還是用 hashmap實現的又簡單,又快

但是hashmap還是不夠快,因為每次查詢字元是不是包含時,都要hash 和查詢。

於是我用bitset 實現了乙個以位標誌方法的演算法,1000000次迴圈 只需要 11ms.

結論: 大牛的話也不能完全相信,一切優美演算法都要以實際測試結果為準。

bitset 實現原始碼:

public boolean checkifin(mybitset set) 

} return true;

}

以上的都以大字串是多次使用為前提, 如果每次都不一樣的話,簡單的loop卻是最佳方案。因為建立hashmap的成本也很高。

Google 的面試題

一輛學校班車裡面能裝多少個高爾夫球?你被縮小到只有硬幣厚度那麼點高 不是壓扁,是按比例縮小 然後被扔到乙個空的玻璃攪拌器中,攪拌刀片一分鐘後就開始轉動。你怎麼辦?要是讓你清洗整個西雅圖的所有窗子,你會收取多少費用?怎麼才能識別出電腦的記憶體堆疊是向上溢位還是向下溢位?你要向你8歲的侄子解釋什麼是資料...

Google面試題(六)

題目 對現在的stack 棧 資料結構進行改進,加乙個min 功能,使之能在常數,即o 1 時間內給出棧中的最小值。可對push 和pop 函式進行修改,但要求其時間複雜度都只能是o 1 分析 要使pop,push,min都是o 1 所以肯定要犧牲點空間 思路 1 在stack的資料結構中加兩個個字...

google雜湊面試題

題目 在乙個字串中找到第乙個只出現一次的字元。如輸入abaccdeff,則輸出b。用雜湊表解題 分析 這道題是2006年google的一道筆試題。解 由於字元 char 是乙個長度為8的資料型別,因此總共有可能256 種可能。於是我們建立乙個長度為256的陣列,每個字母根據其ascii碼值作為陣列的...