Container with Most Water
Question
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai)
. n vertical lines are drawn such that the two endpoints of line i is at (i, ai)
and (i, 0)
. Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Notice
You may not slant the container.
Example
Given [1,3,2], the max area of the container is 2.
Tags
Two Pointers Array
Related Problems
Medium Trapping Rain Water
Analysis
求灌水最多的两个柱子组合,与Trapping Rain Water有一些类似。联想到使用Two Pointers的方法。
two pointers方法需要确定 1. 何时两个pointers终止移动跳出循环,能够包含所有情况。这里仍然是left&right pointers相遇。 2. 何时移动左右pointers。灌水多少不仅与两个柱子的高度有关,也与两个柱子的距离有关。如何使得存放的水更多呢?较短的那一个柱子决定了灌水的area,因此可以移动指向较短的柱子的pointer,对于相会的pointer,一般趋势均为向中间移动,因此如果 heights[left] < heights[right]
,则left++
,反之right--
。
比如,对于如下一个数组heights[]:
应该如何移动pointers?
初始情况下,left = 0
, right = 5
, heights[0] = 1
, heights[5] = 2
,也就是 area = 5 * 1 = 5
; 因为heights[left] < heights[right]
,因此left++
, left = 1
,更新后area = 4 * 2 = 8
; 这时,heights[left] > heigths[right]
,于是right--
, right = 4
, 更新后area = 3 * 3 = 9
; 依次类推,当left
,right
相遇时,循环结束,得到最大area为9
.
问题:为何较短的pointer向中间移动?
可以假设两个柱子距离为n
, 较短的柱子高度为h
,那么中间可以存放水的area为n * h
。 假设初始状态下heights[left] < heights[right]
。
如果令left++
,此时柱子距离为n - 1
,同时较短柱子为h1
,那么area1 = (n - 1) * h1
; 如果令right--
,此时柱子距离n - 1
,同时较短柱子为h2
,那么area2 = (n - 1) * h2
;
两个方向得到的面积之差:
area1 - area2 = (n - 1) * h1 - (n - 1) * h2 = (n - 1) * (h1 - h2)
假定 n - 1 >= 1
,(n - 1 < 0 说明heights[]为空,n - 1 < 1说明 n = 1,则仅有一种area,不必讨论)
做一下不等式变换
area1 - area2 >= h1 - h2
因为heights[left] < heights[right]
的设定,(并只考虑left/right中间的柱子高于两侧的情况,因为如果低于heights[left]
, heights[right]
将无法得到更大的水面积)如果right--
,水位的最高高度将小于left++
时,水位的最高高度。
Solution
Two Pointers
Two Pointers (Updated)
Last updated