题目
给定一个长度为 n
的整数数组 height
。有 n
条垂线,第 i
条线的两个端点是 (i, 0)
和 (i, height[i])
。
找出其中的两条线,使得它们与 x
轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
示例 1:
输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入:height = [1,1] 输出:1
提示:
n == height.length
2 <= n <= 105
0 <= height[i] <= 104
class Solution {
public:
int maxArea(vector<int>& height) {
int max_area = 0;
int n = height.size(); // 获取高度数组的长度
// 使用双指针法
int left = 0;
int right = n - 1;
while (left < right) {
// 计算当前容器的面积
int h = std::min(height[left], height[right]);
int width = right - left;
int area = h * width;
// 更新最大面积
max_area = std::max(max_area, area);
// 移动较短的那条边的指针
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return max_area;
}
};
代码解释
-
获取高度数组的长度:
int n = height.size();
- 使用
size
方法获取height
向量的长度。
- 使用
-
初始化变量:
int max_area = 0; int left = 0; int right = n - 1;
max_area
用于存储最大面积。left
和right
分别是左右指针,初始位置分别是数组的起始和末尾。
-
使用双指针法:
while (left < right) { int h = std::min(height[left], height[right]); int width = right - left; int area = h * width; max_area = std::max(max_area, area); if (height[left] < height[right]) { left++; } else { right--; } }
- 使用
while
循环,直到left
和right
相遇。 - 计算当前容器的高度
h
,取height[left]
和height[right]
中较小的一个。 - 计算当前容器的宽度
width
,即right - left
。 - 计算当前容器的面积
area
,即h * width
。 - 更新
max_area
,取当前max_area
和area
中较大的一个。 - 移动较短的那条边的指针,以尝试找到更大的面积。
- 使用
-
返回结果:
return max_area;
- 返回最大面积。
解释
- 双指针法:通过两个指针分别从数组的两端向中间移动,每次移动较短的那条边的指针,以尝试找到更大的面积。
- 面积计算:容器的面积由较短的那条边的高度和两条边之间的距离决定。
- 优化:这种方法的时间复杂度是 O(n),比双重循环的 O(n^2) 更高效
这个代码。键盘的一个地方在于,没办法控制它的宽度,如果通过双循环暴力破解的话,实际上宽度的定义是错误的,所以计算出来的结果一定是错的。反倒是这种双指针while循环得出来的结果。应该会是正确的,而且更加准确。