今天分享一道非常著名的筆試題,曾經在多個大廠招聘中出現過, 有時在筆試題裏面,有時面試環節中。其實主要是考察程序員對這類問題的處理的算法和思路,到底難不難的呢,菜鳥也能手撕這道大廠的題,不信今天我就給大家庖丁解牛看看。
1
硬幣分類
題目:
現在我有27枚硬幣,其中有一枚假幣,假幣跟真幣長得一摸一樣,但是稍微重一些。擺在桌上有一個稱重天平,要求用最小的次數找出假幣,並寫出算法代碼。
經常面試的同學是不是有點面熟這道題目,碰到這樣的題目,千萬不要慌,也不要上來就動筆。正確的姿勢是應該先想好算法,再下筆敲鍵盤。如果你上來都沒有思考,就開始鬍子眉毛一把抓,一定會自亂陣腳,浪費時間不說,還會敗下陣來!
1
算法和思路
首先我們要思考一下這個問題的解法,大部分人一上來想到的都說對開。就是把硬幣分成兩份,比如假如我們有9個硬幣,各4各一份,然後對這個4個硬幣進行稱重。那麼可能有3個結果:
1).運氣最好的情況,兩份完全相等,剩下的1個就是假幣
2).第一組更重,然後繼續二分稱重
3).第二組更重,然後繼續類似上面第二種情況進行稱重
我們需要3次才能找到,這個是不是最優的解法呢,顯然不是,何況現在的題目是27枚硬幣!
正確的姿勢是什麼的,我們應該採用的是分而治之的方法,我們還是先拿簡單的9枚舉例,把9枚硬幣分成3份,3,3,3,然後稱重,應該是3種結果:
1).第一組和第二組一樣重,那麼假的在第三組裏面,再稱一次即可找出;
2).第一組更重,那麼假的在第一組,再稱一次即可;
3).第二組更重,那麼假的在第二組,再稱一次即可;
這個的算法,看起來更簡介,大概需要2次,如果是27枚,只要多分一次9,9,9 ,最後3次即可。
3
算法Python實現
理清了思路,下面就是開始準備寫代碼了。我們一點一點庖丁解牛似的來寫算法,整個算法無非要解決3個問題:
第一,把硬幣分3組;
第二,把分組的硬幣稱重;
第三,遍歷尋找最重的裏面的假幣
整塊的問題,我們已經分解成小塊的了。下面就是把整個的算法用代碼實現,然後串起來即可。
1).分組問題
拿到一串硬幣,我們需要分成3等份,直接用切片把列表切割一下即可。
2).硬幣稱重
兩種硬幣進行稱重對比,這個其實用一行代碼也能搞定,但是那樣寫的話,閱讀起來不清洗,其實我個人覺得if/elif/else 蠻好的。
3).尋找假幣
這個裏面分兩步走,第一步先尋找假幣,就是給你3組,進行判斷
很好理解,如果第一組和第二組對比稱重,左邊重,那麼假幣就在第一組中;如果第二組重,就是右邊重,那麼假幣就在第二組重,如果都不是,假幣在第三組中。
4).遍歷尋找
times 用於記錄搜索的次數,而search_list是一個可變的列表,每次稱重完了之後,它會變成三分之一的長度,不斷的縮小,直到搜索結束。
其實這樣分而治之一步一步的解析這道題目,看起來也不是很難的。類似的問題有很多,比如水桶問題,過橋的問題,還有蠟燭燒繩子的問題。這些常見的面試題,對於菜鳥來說一定一定要提前準備,老鳥也能溫故而知新。
都說算法是程序的靈魂,要想功力深,先把算法弄成針!加油把,少年!
最後留個彩蛋,悄悄的說一句,上面的代碼其實思考不成熟,有一個bug!哪位厲害的同學看出來,可以在留言區吱一聲。
近期熱門:
程序員GitHub
菜鳥學Python原班人馬打造專注於分享GitHub上有趣的資源包括Python,Java,Go語言前端學習等優質的學習資源分享程序員圈的新鮮趣事,熱門乾貨,職場感悟點的“在看”,否則就看不到我了555