题目
给定一个长度为 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
解题思路
这个问题可以通过使用双指针法来解决。双指针法的基本思想是,使用两个指针分别指向容器的两侧边界,然后根据高度较小的一侧向内移动,从而找到可能的最大水容量。具体步骤如下:
- 1.初始化两个指针,一个指向数组的开头 (left),一个指向数组的末尾 (right)。
- 2.计算当前两个指针指向的容器的水容量,即 min(height[leftl, height[right])*(right - left)。
- 3.更新最大水容量,如果当前水容量大于之前的最大水容量。
- 4.比较两侧边界的高度,将高度较小的一侧向内移动一步。
- 5.重复步骤2-4,直到两个指针相遇。
最后,返回最大水容量作为结果。
代码
c++
class Solution {
public:
int maxArea(vector<int>& height) {
int left = 0; // 左边界指针
int right = height.size() - 1; // 右边界指针
int max_area = 0; // 最大水容量
while (left < right) { // 当左边界指针小于右边界指针时循环
int h = min(height[left], height[right]); // 当前容器的高度取决于较小的一侧
int w = right - left; // 当前容器的宽度
int area = h * w; // 当前容器的水容量
max_area = max(max_area, area); // 更新最大水容量
if (height[left] < height[right]) { // 如果左边界的高度小于右边界的高度,则将左边界向右移动一步
left++;
} else { // 否则将右边界向左移动一步
right--;
}
}
return max_area; // 返回最大水容量作为结果
}
};
golang
func maxArea(height []int) int {
left := 0 // 左边界指针
right := len(height) - 1 // 右边界指针
maxArea := 0 // 最大水容量
for left < right { // 当左边界指针小于右边界指针时循环
h := min(height[left], height[right]) // 当前容器的高度取决于较小的一侧
w := right - left // 当前容器的宽度
area := h * w // 当前容器的水容量
if area > maxArea { // 更新最大水容量
maxArea = area
}
if height[left] < height[right] { // 如果左边界的高度小于右边界的高度,则将左边界向右移动一步
left++
} else { // 否则将右边界向左移动一步
right--
}
}
return maxArea // 返回最大水容量作为结果
}
func min(a, b int) int { // 辅助函数,返回两者中较小的数
if a < b {
return a
}
return b
}