给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
n == height.length
2 <= n <= 105
0 <= height[i] <= 104
耗时久,性能差
这个问题是著名的“盛水最多的容器”问题,可以通过双指针法来高效地解决。该算法的关键在于逐步缩小范围,同时记录能够容纳的最大水量。
给定一个整数数组 height
,我们需要找到两个索引 i
和 j
(其中 i < j
),使得 min(height[i], height[j]) * (j - i)
的值最大。这就是容器的最大水容量。
初始化双指针:
设置两个指针,左指针 left
初始化为数组的起始位置 0
,右指针 right
初始化为数组的终止位置 n-1
,其中 n
是数组的长度。
计算当前水容量:
在每一步中,计算由 left
和 right
指针所确定的容器的水容量:min(height[left], height[right]) * (right - left)
。
如果这个容量比目前记录的最大容量要大,就更新最大容量。
移动指针:
由于水容量受限于短板(较短的那一边),我们选择移动高度较小的一端指针(即 height[left]
和 height[right]
中较小的那一个)来尝试寻找更长的高度。
如果 height[left] < height[right]
,就把 left
指针右移(left++
),否则就把 right
指针左移(right--
)。
重复步骤2和步骤3,直到两个指针相遇。
输出结果:
当两个指针相遇时,已经找到了最大水容量,输出这个最大值。
时间复杂度:O(n),其中 n
是数组的长度。每个元素最多被访问一次。
空间复杂度:O(1),只使用了常量级别的额外空间。
对于 heights = [1,8,6,2,5,4,8,3,7]
,上述代码将输出 49
。这对应于垂线索引 1
和 8
,它们之间的距离是 7
,较短的垂线高度是 7
,因此水容量是 7 * 7 = 49
。
这个算法通过聪明地选择指针移动来高效地找到最优解,并且避免了冗余计算。
字数统计 |
JavaScript版本实现: