描述
给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水。
方法
容积=最短边*底边
左指针left从数组首向右扫描,右指针right从数组尾向左扫描,
起始时刻,left指向首元素,right指向尾元素,容积=min(height[left],height[right])*(right-left)。
此时,左右两条边中有一条较短的边,不妨假设height[left]<=height[right],即左边的边较短。
下面有两种走法:
(1)左指针向右移动一步
容积=min(height[left+1],height[right])*(right-left-1)
height[right]不变,height[left+1]可能变大、也可能变小,(right-left-1)变小,容积有可能变大。
(2)右指针向左移动一步
容积=min(height[left],height[right-1])*(right-1-left)
height[left]不变,又因为height[left]<=height[right],所以最短边长min(height[left],height[right-1])不会变大,底边长(right-1-left)变小,容积变小。
因此,为寻找容积最大值,应当使较短边的指针移动(相当于进行了剪枝,已知某部分搜索空间不可能存在更优解,便不再搜索这一部分空间)。
搜寻终止条件:left>=right,变量res维护最大容积。
C++代码
class Solution {
public:
int maxArea(vector<int>& height) {
//排除不能形成容器的情况
if(height.size() < 2)
return 0;
int res = 0;
//双指针左右界
int left = 0;
int right = height.size() - 1;
//共同遍历完所有的数组
while(left < right){
//计算区域水容量
int capacity = min(height[left], height[right]) * (right - left);
//维护最大值
res = max(res, capacity);
//优先舍弃较短的边
if(height[left] < height[right])
left++;
else
right--;
}
return res;
}
};