给定一个长度为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 <= 10^5
0 <= height[i] <= 10^4
解答
本体很明显需要使用动态规划的方法,但在动态规划的过程中如何将所有的情况都考虑进去比较复杂。水的“体积”可以用底和高度最低的边界的乘积表示,如果从左往右进行动态规划,底是逐渐增加的,因为要寻找最大体积,所以体积也在动态规划中逐渐增加,这样比较难以比较。但如果使用双指针同时从左右两边减小底,就相对容易比较。本体的解题步骤如下:
- 水的体积为
(right - left) * min(height[left], height[right])
- 当
height[left] > height[right]
时,由于水的体积由height[right]
决定,因此我们应该将right
向左移动,以寻找一个更加大的height[right]
值以获得更大的水的体积。 - 循环停止条件
left > right
代码
class solution{
public:
int maxArea(vector<int>& height){
int res = (height.size() - 1) * min(height[0], height.back());
int left = 0, right = height.size() - 1;
while (left < right) {
int area;
if (height[left] > height[right]) {
area = (right - left) * height[right];
right--;
}
else {
area = (right - left) * height[left];
left++;
}
res = max(res, area);
}
return res;
}
};
本文题目及部分解答来自力扣:盛最多水的容器