描述
给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水
1.你不能倾斜容器
2.当n小于2时,视为不能形成容器,请返回0
3.数据保证能容纳最多的水不会超过整形范围,即不会超过231-1
数据范围:
0<=height.length<=1050<=height.length<=105
0<=height[i]<=1040<=height[i]<=104
如输入的height为[1,7,3,2,4,5,8,2,7],那么如下图:
【解法一】O(N^2)解法
class Solution {
public:
int maxArea(vector<int>& height) {
// write code here
int n = height.size();
if(n < 2)return 0;
int res = 0;
for(int i = 0; i < n-1; i++)
{
for(int j = i+1; j < n; j++)
{
int _minheight = min(height[i], height[j]);
res = max(res, (j-i)*_minheight);
}
}
return res;
}
};
【解法二】双指针对撞
这道题利用了水桶的短板原理,较短的一边控制最大水量,因此直接用较短边长乘底部两边距离就可以得到当前情况下的容积。但是要怎么找最大值呢?
可以利用贪心思想:我们都知道容积与最短边长和底边长有关,与长的底边一定以首尾为边,但是首尾不一定够高,中间可能会出现更高但是底边更短的情况,因此我们可以使用对撞双指针向中间靠,这样底边长会缩短,因此还想要有更大容积只能是增加最短变长,此时我们每次指针移动就移动较短的一边,因为贪心思想下较长的一边比较短的一边更可能出现更大容积。
class Solution {
public:
int maxArea(vector<int>& height) {
// write code here
if(height.size()<2)return 0;
int res = 0;
int left = 0, 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;
}
};