You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]).
Find two lines that together with the x-axis form a container, such that the container contains the most water.
Return the maximum amount of water a container can store.
Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49
Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
# $\forall j\in fences,\forall 1\le p< j,h_p< h_j$ fences = [0] max_height = heights[0] for i inrange(1, n): h_i = heights[i] if max_height < h_i: fences.append(i) max_height = h_i continue
j = self._find_min_ge(fences, heights, h_i) max_area = max(max_area, (i - j) * h_i)
return max_area
def_find_min_ge_slow(self, fences: List[int], heights: List[int], h: int) -> int: for j in fences: if heights[j] >= h: return j
def_find_min_ge(self, fences: List[int], heights: List[int], h: int) -> int: """Finds the minimal j, where j in fences, and heights[j-1] < h <= heights[j]. Constraints: - heights[fences[-1]] >= h """ l, r = 0, len(fences) - 1 while l <= r: m = (l + r) >> 1 if (m_h := heights[fences[m]]) == h: return fences[m] elif m_h < h: l = m + 1 else: r = m - 1
return fences[l] if heights[fences[l]] > h else fences[l + 1]
Improve
先看最两边的竖线 i = 1、j = n 围起来的容器 Ci,j,是所有可能容器中最宽的,其高度为 hi,j=min{hi,hj}。
其他容器的宽度一定比这个窄,只有当高度更高时,才有可能比 Ci,j 面积大。
假设 hi≤hj,看 i 右边的竖线,如果 hi+1≤hi,那么 Ci+1,j 的面积只会更小。
从 i + 1 开始向依次右找,如果能找到一个 k(i < k < j),hk>hi,用竖线 k 和 j 围起来的容器 Ck,j 高度更高,面积有可能更大一些。