題目
給定 n 個非負整數 a1,a2,...,an,每一個數表明座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別爲 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器能夠容納最多的水。python
說明:你不能傾斜容器,且 n 的值至少爲 2。數組
圖中垂直線表明輸入數組 [1,8,6,2,5,4,8,3,7]。在此狀況下,容器可以容納水(表示爲藍色部分)的最大值爲 49。app
從大到小排序
維護三個變量:
當前的最低高度,當前最左,當前最右
最大面積就是 當前高度 × (當前最右 - 當前最左)spa
class Solution: def maxArea(self, height: List[int]) -> int: x = [] for i, n in enumerate(height): x.append((i, n)) x.sort(key=lambda x:x[1], reverse=True) h = min(x[0][1], x[1][1]) l = min(x[0][0], x[1][0]) r = max(x[0][0], x[1][0]) ans = h * (r - l) for i in range(2, len(x)): l = min(x[i][0], l) r = max(x[i][0], r) h = min(h, x[i][1]) ans = max(ans, h * (r - l)) return ans
這個問題的最優解有一個特色:
若是 i 和 j 位置是最大容量,則要麼 「i 是 0 到 i 中高度最高的」 要麼 「j 是從 j 到最後中 高度最高的」。
由於若是兩個都不知足,選擇這兩個最高的獲得的容量必定比 i,j 容量要高。指針
因此這樣能夠採起先令 i = 0, 令 j = len(height)code
而後循環計算當前容量,每次循環若是 i 的高度大於 j 則 j-= 1
若是 i 的高度小於 j 則 i -= 1
。blog
記錄下過程當中的最大容量,就是答案。排序
class Solution: def maxArea(self, height: List[int]) -> int: i = 0 j = len(height)-1 ans = 0 while i < j: ans = max(ans, (j - i) * min(height[i], height[j])) if height[i] < height[j]: i += 1 else: j -= 1 return ans