[Leetcode]11. 盛最多水的容器

給定 n 個非負整數 a1,a2,...,an,每個數代表坐標中的一個點 (i, ai) 。在坐標內畫 n 條垂直線,垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。
說明:你不能傾斜容器,且 n 的值至少為 2。


question_11.jpg

圖中垂直線代表輸入數組 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示為藍色部分)的最大值為 49。

  • 示例:
    輸入: [1,8,6,2,5,4,8,3,7] 輸出: 49

笨方法

既不是單純的找寬度最寬的兩點,也不是找高度最高的兩點,而是要找高*寬最大的參數。暴力搜索肯定是一種解決方案,但絕不是效率最高的方式。最好是能夠線性搜索。

能否用遞歸的思想解決,或者用二分法解決?遞歸看起來不怎么靠譜,因為局部能夠容納的最多水量與總體水量沒有必然關系。二分法似乎也不行,如果所有的矮柱子都分布在左邊,所有的高柱子都分布在右邊,而高柱子又遠遠高于矮柱子,這時最大容水量的矩形應該在右側。

先用暴力搜索來處理吧,處理過程中應當注意:index和value都需要用到。考慮到兩兩柱子的匹配存在重復,應可減少一半的比對時間。

代碼倒是挺簡單的,但是執行效率肯定不高。時間復雜度O(n^2),果然超時了。

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        area=0
        for i,c in enumerate(height):
            for i1,c1 in enumerate(height):
                if i1>i and (i1-i)*min(c,c1)>area:
                    area=(i1-i)*min(c,c1)
        return area
class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        area=0
        l=len(height)
        for i,c in enumerate(height):
            for j in range(i+1,l,1):
                area=max(area,(j-i)*min(c,height[j]))
        return area

聰明方法

采用官方題解中的雙指針法,其基本原理是:左右兩端各一個指針,如果其中一端的長度小于另一端的長度,則移動較短的那一端。因為容器的容量受較短的那個線段影響,而不會受較長的線段影響。每次移動都記錄當前的最大面積。

相對于笨方法,此方法的核心提升點在于:用了雙指針。移動指針的時候,可以比較兩個線段的長度后,再決定移動哪一個。
向內移動較長的線段時,由于寬度減少了,最短線段的長度不可能增加,因此總面積必然減少。所以,只需要向內移動較短的線段就行了,盡管寬度也減少了,但最短線段的長度可能會增加,從而導致總面積可能增加。

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        area=0
        l,r=0,len(height)-1
        while l<r:
            area=max(area,(r-l)*min(height[l],height[r]))
            if height[l]<height[r]:
                l+=1
            else:
                r-=1
        return area
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 描述: 給定 n 個非負整數 a1,a2,...,an,每個數代表坐標中的一個點 (i, ai) 。在坐標內畫 n...
    大數據Zone閱讀 409評論 0 1
  • 題目:11. 盛最多水的容器 難度:中等 分類:數組 解決方案:雙指針 今天我們學習第11題盛最多水的容器,這是一...
    編程半島閱讀 638評論 0 1
  • 給定 n 個非負整數 a1,a2,...,an,每個數代表坐標中的一個點 (i, ai) 。在坐標內畫 n 條垂直...
    小小堯閱讀 505評論 0 0
  • 音樂廳的燈光暗下來,舞臺被光束托起 一架鋼琴,數把小提琴和大提琴,一只手風琴 激情流淌于它們被深愛的那一刻 記憶纏...
    蔣菱閱讀 227評論 0 1
  • 知識的海洋沒有底線。每個人都在不斷的探索中。 以前對弟弟的各種問題總是積極回答。現在對自己提出的問題有點敷...
    南來北往中閱讀 246評論 0 1