twitter面試題之裝水問題

這篇文章最初發(fā)在CSDN上,現(xiàn)在轉(zhuǎn)到簡書,還是比較喜歡簡書簡約的風(fēng)格。

據(jù)說這是twitter的一個面試題,不過,去年找工作的時候我的一個同學(xué)在面試微軟的時候也有問到這個問題。很有意思的一個題目,當(dāng)時我也沒有去深究到底怎么實現(xiàn)比較好,幾天前在伯樂在線上面看到了這篇文章面試題分析:我的Twitter技術(shù)面試失敗了, 才知道這個解法原來很簡單,只是剛開始沒怎么看懂,比較繞。好吧,廢話少說,我還是根據(jù)自己的理解來說下這個問題,不對之處,還請大家指正。

題目描述

看下面這個圖片,在這個圖片里我們有不同高度的墻。這個圖片由一個整數(shù)數(shù)組所代表,數(shù)組中每個數(shù)是墻的高度。上邊的圖可以表示為數(shù)組[2,5,1,2,3,4,7,7,6],假如開始下雨了,那么墻之間的水坑能夠裝多少水呢?”


以1×1的方塊為單位計算容積。所以,在上邊的圖中下標(biāo)為1以左的都會漏掉。下標(biāo)7以右的也會漏掉。剩下的只有在1和6之間的一坑水,容積是10。如下圖所示。

分析

原文作者最初想法是用極大值考慮,也就是說找到下標(biāo)2的左右兩個極大值,但是這個做法最后作者意識到是錯誤的。比如下面的情況就不對:
看看這個輸入:



如果答案計算的是極大值之間的水,就像這樣。



但是答案應(yīng)該是在兩個高塔之間只有一池水:

那其實正確的解法是作者后來靈光一閃想到的,確實看起來很簡單。這其實要基于一個事實那就是,你從左往右掃描數(shù)組的時候,只要是左邊最大值小于右邊的數(shù)字時,這中間是一定可以存儲水的。每次維護(hù)一個左墻的最大值,從左向右的掃描過程中遇到大于左邊最大值的值,則更新左邊最大值,并且不增加存儲水的容量,因為在從左往右掃描的過程中,如果遇到的值比左邊大,那么存儲不了水,如上面例子中從2開始掃描,遇到5的時候,此時存儲容量還是0,因為5大于2,這中間存儲不了水。從右往左掃描也是一樣。

一個基本的解法就是先找到數(shù)組最大值,然后從左往右掃描到最大值,計算出水的容量;然后從右往左掃描到最大值,計算出水的容量,最后總的容量就是兩部分之和。

描述還是會不怎么清楚,還是以例子來看。以第一個例子[2,5,1,2,3,4,7,7,6]來看,最大值為7,兩個7隨便選后面一個好了。那么從左往右掃描過程如下:

  • 1)首先設(shè)置左邊最大值為2,容量設(shè)置為0。
  • 2)2小于7,往右繼續(xù)掃描,遇到5,因為5大于2,所以更新左邊最大值為5,此時并不更新存儲水的容量,接著往后掃描。
  • 3)掃描到1,因為1比前面的5小,因此現(xiàn)在至少可以存儲5-1=4單位水。存儲水的容量加4。因為我們知道右邊有比左邊最大值還大的值,所以肯定是可以至少存儲這么多水的。
  • 4)接著掃描到2,還是比5小,存儲水的容量增加5-2=3,容量變?yōu)?+3=7.
  • 5)繼續(xù)掃描到3,還是比5小,存儲水的容量增加5-3=2,容量變?yōu)?+2=9.
  • 6)繼續(xù)掃描到4,還是比5小,存儲水的容量增加5-4=1,容量變?yōu)?+1=10.
    可以得到左側(cè)存儲水的容量為10。同理,從右往左掃描到7,容量為0,因為6小于7,7以右的水全部會漏掉。

那么一個更優(yōu)的解法其實是只需要掃描一遍就OK,不需要之前掃描數(shù)組找最大值,也就是整合了左右掃描的過程。如果左邊值小于右邊值,則從左往右掃描,否則從右往左掃描。(附python代碼在后面)

代碼

def calculate(testcase):
    p_l = 0
    p_r = len(testcase) - 1
    max_l = testcase[p_l]
    max_r = testcase[p_r]

    volume = 0
    while p_r > p_l :
        if max_l < max_r:
            p_l = p_l + 1
            if testcase[p_l] >= max_l:
                max_l = testcase[p_l]
            else:
                volume = volume + (max_l - testcase[p_l])
        else:
            p_r = p_r - 1
            if testcase[p_r] >= max_r:
                max_r = testcase[p_r]
            else:
                volume = volume + (max_r - testcase[p_r])
    return volume

參考資料

伯樂在線:面試題分析:我的Twitter技術(shù)面試失敗了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,759評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,886評論 18 139
  • 所有知識點已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)? 在 Jav...
    侯蛋蛋_閱讀 2,497評論 1 4
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,360評論 11 349
  • 如果硬要找一本這些年對我影響比較大的教育書籍的話,恐怕要算巴西教育家保羅?弗雷勒的《十封信——寫給膽敢教書...
    凌宗偉閱讀 972評論 0 2