LeetCode(11) 盛最多水的容器

2022-05-07 09:27:09 字數 2039 閱讀 2500

medium!

題目描述:

給定 n 個非負整數 a

1,a2,...,a

n,每個數代表座標中的乙個點 (i, ai

) 。畫 n 條垂直線,使得垂直線 i 的兩個端點分別為 (i, ai

) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。

注意:你不能傾斜容器,n 至少是2。

解題思路:

我們需要定義i和j兩個指標分別指向陣列的左右兩端,然後兩個指標向中間搜尋,每移動一次算乙個值和結果比較取較大的,容器裝水量的演算法是找出左右兩個邊緣中較小的那個乘以兩邊緣的距離,**如下:

1

class

solution

9return

res;10}

11 };

下面這種方法是對上面的方法進行了小幅度的優化,對於相同的高度們直接移動i和j就行了,不再進行容量計算了,參見**如下:

1

class

solution

11return

res;12}

13 };

使用貪心演算法 

1.首先假設我們找到能取最大容積的縱線為 i, j (假定i < j),那麼得到的最大容積 c = min( ai , aj ) * ( j- i) ; 

2.下面我們看這麼一條性質: 

①: 在 j 的右端沒有一條線會比它高!假設存在 k |( j < k && ak > aj) ,那麼 由 ak > aj,所以 min(ai, aj, ak) =min(ai, aj) ,所以由i, k構成的容器的容積c』 = min(ai, aj) * (k - i) > c,與c是最值矛盾,所以得證j的後邊不會有比它還高的線; 

②:同理,在i的左邊也不會有比它高的線;這說明什麼呢?如果我們目前得到的候選: 設為 x, y兩條線(x< y),那麼能夠得到比它更大容積的新的兩條邊必然在[x, y]區間內並且 ax』 >= ax , ay』 >= ay; 

3.所以我們從兩頭向中間靠攏,同時更新候選值;在收縮區間的時候優先從x, y中較小的邊開始收縮;

1

class

solution

14else

2021}

22return

max;

23}

24 };

逼近法 

每次左右兩端都捨去短的那一端 

若選擇短的那一端【s=小於等於此端的高*小於等於當前的最大區間長度】,至多的面積也是選擇最左最右的乙個矩形,因此不必再考慮短的一端,直接捨去逼近

1

class

solution

10return

_m;11

}12 };

通過設定兩個指標,分別指向陣列的頭和尾,計算容器可以容納多少水,然後比較頭指標和尾指標對應的高度,矮的那個前進或後退一步(很好理解)。

1

class

solution:

2def maxarea(self, height):

3"""

4 :type height: list[int

]5 :rtype: int

6"""

7 l = 0

8 r = len(height) - 1

9 contain = 0

10while l 11 contain = max(contain, (r - l) *min(height[l], height[r]))

12if height[l] >height[r]:

13 r -= 1

14else

:15 l += 1

1617

return contain

leetcode11 盛最多的水

題意 給出乙個陣列表示乙個容器,陣列中的每個數字表示容器中每個柱子的高度,每兩根柱子中的間距為1,問該容器最大的盛水量。思路1 暴力法 最簡單的思路就是暴力遍歷,乙個迴圈從頭到尾,乙個迴圈從尾到上乙個迴圈指向的位置,計算每兩根柱子之間的盛水量,將最大的盛水量返回。public int maxarea...

leetcode 11 盛最多的水

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

LeetCode 11 盛最多水的容器

給定 n 個非負整數 a1,a2,an,每個數代表座標中的乙個點 i,ai 畫 n 條垂直線,使得垂直線 i 的兩個端點分別為 i,ai 和 i,0 找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。注意 你不能傾斜容器,n 至少是2。左右指標法 首先指標指向最左 最右 當左邊的高...