题目:给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
运用双指针法,分别标记数组头部与数组尾部,向中间靠近。
双指针法的证明:
因为要求的是容纳最多的水,在两个标记相聚最远处,构成长方形容器的长最大。然后比较这两个标记值的大小,较小的那个往中间移动。
每移动一次就进行一次容量的计算,并与当前容量最大值进行比较。
然后再次移动两个值中较小的一个,直到两个标记相遇,结束程序。
很显然,时间复杂度为O(n)。
为什么移动较小的一方是正确的:
如图所示,初始标记为第一个和最后一个,代表的值分别为1和7,当前面积为min(1, 7) * 9 = 9。
如果保持较小的值不变,移动较大的值,假设为y
1
_1
1,与第一个的距离为s,则面积为min(1, y
1
_1
1) * s,显然min(1,y
1
_1
1) <= min(1, 7),s < 9,所以min(1, y
1
_1
1) * s < min(1, 7) * 9。
可见当移动值大的一方时,面积永远比原来的小,所以必须移动值小的一方,并且移动以后,原来的值就相当于抛弃了。于是数据规模从n变成了n-1,以此类推,就可以结束循环,找到最大的容量。