目錄
問題
給定 n 個非負整數 a1,a2,...,an,每個數代表座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別爲 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。
說明:你不能傾斜容器,且 n 的值至少爲 2。
圖中垂直線代表輸入數組 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示爲藍色部分)的最大值爲 49。
示例:
輸入: [1,8,6,2,5,4,8,3,7]
輸出: 49
解題思路
分析:這題,題目中感覺有盲點:容積的定義計算模糊。看了官方的題解,準確的題目,應該是求解給定的垂直線間與座標軸構成的矩形區域的面積最大。考點大概就是木桶原理,矩形的高度由較短的那個垂線段決定。
1)一種簡單的實現方法:即暴力實現,但算法的時間複雜度太高:。
2)這裏我們分析另一種實現方法——所謂的雙指針實現:
a. 在給定的垂直線段構成的數組,分別在開頭和結尾,放上標記left和right(初始值對應數組的開始結尾的小標);
b. 然後求解這兩垂直線間與座標軸構成的矩形區域面積,矩形的高度即爲較短的那個垂線段值,寬度爲right-left,判斷比較存儲每次計算得到的面積值和當前記錄的最大面積值中的最大值;
c. 之後,如果是left標記的值小於right標記的值,則left=left+1,否則,right=right-1;
數組遍歷一遍即可得到結果,whle循環實現,條件即爲left<right。對於輸入的數組長度小於2,即特殊情況的處理,返回0即可。
詳細過程描述,如上分析,程序具體如下:
python具體實現
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
if len(height)<2: # 數組長度的特殊情況
return 0
# 雙指針實現
left,right = 0,len(height)-1
maxArea = 0 # 記錄最大的矩形面積
while(left<right):
tempArea = min(height[left],height[right])*(right-left) #當前遍歷到的矩形面積
if tempArea>maxArea: # 記錄最大值
maxArea = tempArea
if height[left]>height[right]: #雙指針的移動方式
right =right - 1
else:
left =left + 1
return maxArea
題外話
這道題,隱含着另一部分的數學原理,需要認真體會,不然還真就會暴力處理了。
一遍搞過!