目录
一、问题描述
给定一个长度为 n
的整数数组 height
。有 n
条垂线,第 i
条线的两个端点是 (i, 0)
和 (i, height[i])
。
找出其中的两条线,使得它们与 x
轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
二、解题思路
这个问题要求我们找到两条垂直的线,计算它们与 x 轴构成的容器所能盛放的最大水量。容器的容量由两条线之间的最短线的高度和它们之间的距离决定。我们可以使用双指针的方法来解决这个问题。
核心思想:
- 使用双指针,一个指针从数组的左端开始,另一个从数组的右端开始。
- 每次移动较短的那条线,因为容器的容量是由较短的线决定的,移动较短的线可能会带来更大的水量。
- 逐步计算每次的容器容量,并更新最大值。
三、代码
class Solution {
public int maxArea(int[] height) {
// 初始化两个指针,分别指向数组的两端
int left = 0; // 左指针,从数组最左端开始
int right = height.length - 1; // 右指针,从数组最右端开始
// 初始化最大水量变量
int maxArea = 0;
// 使用双指针法,在左指针小于右指针的情况下继续遍历
while (left < right) {
// 计算当前容器的宽度,即两个指针之间的距离
int width = right - left;
// 容器的高度取决于较短的那条线
int h = Math.min(height[left], height[right]);
// 计算当前的水量,即宽度乘以高度
int currentArea = width * h;
// 更新最大水量,取当前水量和之前的最大水量中的较大值
maxArea = Math.max(maxArea, currentArea);
// 移动较短的那条线的指针,以期找到更高的线从而增大水量
if (height[left] < height[right]) {
left++; // 如果左边的线较短,移动左指针
} else {
right--; // 如果右边的线较短,移动右指针
}
}
// 返回最大水量
return maxArea;
}
}
四、复杂度分析
- 时间复杂度:O(n),n 是数组的长度。我们只遍历数组一次,每次只移动一个指针。
- 空间复杂度:O(1),我们只使用了常数级别的额外空间。