给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
看到题最简单的想法就是用两层循环求出每一个柱子作为一条边能盛水的最大容量,再找出其中的最大值,不过这样的复杂度是O(n^2),在一些测试用例上出现超时的现象。
class Solution {
public:
int maxArea(vector<int>& height) {
if(height.size()<2)return 0;
vector<int> dp(height.size(),0);
int max=0;
for(int i=1;i<height.size();i++){
for(int j=0;j<i;j++){
int min=height[i]<height[j]?height[i]:height[j];
min=min*(i-j);
dp[i]=dp[i]>min?dp[i]:min;
}
max=max>dp[i]?max:dp[i];
}
return max;
}
};
但是其实并不需要知道每一个柱子能盛水的所有值,用双指针从数组两端开始,盛水的量等于两个柱子之间的距离*较短柱子的高度,因此在最外面是距离最大的情况,如果较低的指针向内移动,盛水的量有可能会变大也有可能会变小;如果较高的指针向内移动,盛水的高度一定会变小。因此将两个指针中较小的那个向内移动,直到两者相遇,存储这个过程中最大的盛水量。
class Solution {
public:
int maxArea(vector<int>& height) {
if(height.size()<2)return 0;
int i=0,j=height.size()-1,max=0;
while(i<j){
int shui=0;
if(height[i]<height[j]){
shui=height[i];
shui*=(j-i);
i++;
}
else{
shui=height[j];
shui*=(j-i);
j--;
}
max=max>shui?max:shui;
}
return max;
}
};