盛最多水的容器
盛最多水的容器(Container With Most Water)是一个经典的双指针问题,题目要求在给定的数组中,找出两条线段,使其与 x 轴构成的容器可以容纳最多的水。下面是用Java实现的解决方案:
public class MaxArea {
public int maxArea(int[] height) {
int maxArea = 0;
int left = 0; // 左指针,指向数组的起始位置
int right = height.length - 1; // 右指针,指向数组的结束位置
// 使用双指针向内移动,不断更新最大面积
while (left < right) {
// 计算当前两个指针指向的线段能够容纳的水的面积
int currentArea = Math.min(height[left], height[right]) * (right - left);
// 更新最大面积
maxArea = Math.max(maxArea, currentArea);
// 移动较短的线段,因为移动较长的线段不会使容器的容量增加,而且容器的宽度在减小,要想容积增加,只能期望高度增加。
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return maxArea;
}
}
解释每一步:
-
我们使用两个指针
left
和right
分别指向数组的起始位置和结束位置。 -
初始化最大面积
maxArea
为0。 -
使用双指针向内移动,直到
left
和right
指针相遇为止。 -
计算当前两个指针指向的线段能够容纳的水的面积,即两个指针指向的线段的最小高度乘以宽度(
right - left
)。 -
更新最大面积
maxArea
。 -
移动较短的线段,因为移动较长的线段不会使容器的容量增加,而且容器的宽度在减小,要想容积增加,只能期望高度增加。
这种解法的时间复杂度为 O(n),其中 n 是数组的长度。因为我们只需要遍历一次数组。空间复杂度为 O(1),因为只使用了常数级别的额外空间。