一道Python面試題,硬是沒憋出來,最後憋出一身汗!

Python語言目前是最火的語言之一,語法簡單,功能強大,最新的TIOBE已公佈2020年6月的編程語言排行榜,Python已經連續多個月都在前三甲了,非常火爆!

現在學習Python的同學越來越多,面試的環節,很多面試官讓你任選語言進行編程。Python因爲簡單,很多小夥伴願意用Python進行答題。最近我們的一個粉絲交流羣,有一位同學跟我分享了他面試的經歷。小李學了Python大概有2年多了,他跟我講了前段時間面試某杭州大廠的一道面試題,注意是面試題,不是筆試卷。

現場讓你手寫代碼,壓力山大啊~~也許是因爲緊張的原因,也許是因爲自己算法基礎底子不深的原因,反正現場憋了很久,沒有憋出來。到底是什麼樣的一個算法題呢,一起來看一下。

1

面試的題目

題目:

假設你手上有面值1塊,2塊,5塊各若干張紙幣,你現在需要支付給商家6元錢,請問你有多少種組合,列出每一種組合?

要求:

1).在白板上手寫代碼或者直接在電腦上寫

2).分析你的算法,如何優化

3).對搜索的結果進行分析

看起來這個問題似乎很簡單,就是一個空間組合搜索,然後加起來的面值爲6即可,但是現場面試給你思考的時間,不會超過1分鐘。小李當時就心裏咯噔一下,leetcode的題目少刷了,其實面試之前也準備了,刷了一些算法題,但是還是手生了一些。

大家可以思考一下,如果是你的話,你先不看下面的答案,現場手寫能寫出來嗎?

思路:

這個題目其實網上也很多類似的,就是鈔票的選取方案而已,一般的解法都是遞歸。遞歸只要設計出口即可。如果我們的方案等於6元即退出,如果超過了6元就放棄,如果不足6元就繼續添加更多的鈔票即可。

bills是鈔票面額的列表(假如爲[1,2,5]),然後target是目標值(假如爲6),然後填入一個空列表的方案 solution

  • 如果總金額等於target就打印solution;

  • 如果大於總金額就放棄;

  • 上面兩種都不滿足的時候,就是金額不夠的情況,進行一個遞歸搜索,這裏等於設計一個容器ways(用來存放方案,直接複製solution 列表),然後不斷的加入一張鈔票進行遞歸;

如果能現場寫出來這個代碼,並且運行成功,其實還是蠻厲害的,走到這一步,相信至少能拿到及格的分數了。但是面試官會進行第二次的提問,你覺得這個算法哪裏有問題,怎麼解決?

確實這個裏面有很多重複的方案,比如[1,1,1,1,2]和[1,1,1,2,1]就是完全重複的,我們需要取重複。

2

二次優化

很明顯上面的搜索是大而全的,就是有很多浪費的空間,如果我們的搜索的樣本很大的話,就會有很多浪費的空間,這樣的效率肯定是低的,如何優化呢?

有的同學說可以保存結果然後進行取重複,但是這樣要等整個的結果出來纔行;有沒有辦法在搜索空間算法上動手腳呢?

我們來看一些優化後的代碼:

是不是過濾了很多重複的方案,我們在搜索的方案裏面加一個新參數bigger,就是當前的已經生成的最高的面額,在搜索的過程中,我們只能append那些大於等於已經加入的最高的面額鈔票,低的我們就不賣了。

當然還有其他的解決辦法,其實如果回答出這個參數,相信會給面試官加分不少,說明在工作的時候,並不是一個只知道完成任務的,還是一個喜歡勤思考會優化代碼的人。其實面試的時候回答出這一步,已經是可以拿到良好分了。

3

如何對搜索結果進行分析

上面的結果都是在通過print打印在內存裏面,如果我們需要對整個的搜索的空間進行進一步的處理,比如我們有100種方案,我們需要保存到文件中或者數據庫裏面進一步的分析,如果把遞歸的結果提取出來呢?

第一種,簡單粗暴:

我們直接用全局變量,在整個函數的外部加一個out=[],來存儲所有的組合:

第二種,優雅的方式

全局變量固然簡單,但是在生產的環境的項目裏面,這肯定不是最佳的解法。最好的方法還是在函數內自己存儲,然後我們只要在調用的時候獲取即可。這裏我們用Python裏面的生成器yield來搞定。

通過yield來緩存遞歸過程的結果,是不是非常優雅。這個時候我們對所有的組合可以進行分析,比如我想找到用鈔票最少的組合,就可以這樣:

小編說兩句:

其實整個這道面試題,如果是放在筆試題裏面,相信大部分的同學都可以答出來,難度其實並不大。但是在面試的環節,就會難很多,一個緊張,二個思考的時間非常短,需要平時有深厚的積累!

建議參加大廠的面試,多多少少都要準備一下尤其是算法。一定要多刷一些leetcode的題目,不要照搬照套,一定要理解並且把代碼學到肚子裏去,實在不行,先把代碼思路背下來,這樣有備無患,畢竟臨陣磨槍,不快也光!好了,希望今天的文章對大家有幫助。

近期原創熱門:

程序員GitHub

由菜鳥學Python原班人馬打造的公衆號【程序員GitHub】開始啦!專注於分享GitHub上有趣的資源包括,Python,Java,Go語言,前端學習等優質的學習資源,分享程序員圈的新鮮趣事,熱門乾貨,職場感悟

點的“在看”,否則就看不到我了555
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章