题目链接:盛最多水的容器
在改题中,我们要找出在给定垂直线数组中,两条垂直线所构成的容器可以容纳的最大水量。这个问题可以使用双指针法
来高效解决。
双指针法解决最大容器问题
-
问题描述:给定一个垂直线高度的数组 height,数组下标 i 表示第 i 条垂直线的位置,height[i] 表示该垂直线的高度。
-
目标:找到两条垂直线,使得它们与 x 轴构成的容器可以容纳最多的水。
-
双指针法思路:使用两个指针 i 和 j,分别指向数组的
起始
和末尾
。计算当前指针所指的两条垂直线构成的容器的面积,即面积 = min(height[i], height[j]) * (j - i)
。移动指向较短垂线的指针,以期望找到更高的垂线,从而使得容器的高度增加。因为底边的宽度会减小,但是高度的增加可能会弥补宽度的减小,从而得到更大的面积。重复此过程,直到两个指针相遇为止。 -
代码实现(C++):
class Solution {
public:
int maxArea(vector<int>& height) {
int i = 0, j = height.size() - 1, res = 0;
while (i < j) {
int h = min(height[i], height[j]);
res = max(res, h * (j - i));
if (height[i] < height[j]) {
i++;
} else {
j--;
}
}
return res;
}
};
关于“移动较段垂线”的解释
事实上,无论哪个指针移动,底边宽度都会减小。
但是如果我们移动较短
的垂线对应的指针,就可能在保持高度的情况下,增加底边的宽度
,从而得到更大的面积。
这种方法的正确性在于,我们不会错过可能的更大面积,因为在每一步中,我们都朝着可能更大
的高度前进,而不是底边宽度。
这就是双指针法在解决最大容器问题中的应用。使用这种方法,我们可以在线性时间复杂度内找到能够容纳最多水量的容器。
复杂度分析
- 时间复杂度:
O(N)
——其中 N 是数组的长度,因为我们最多遍历一次数组。 - 空间复杂度:
O(1)
——因为只使用了几个常数额外的变量。