(中等题))
【题目描述】
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
【示例】
示例 2:
输入:height = [1,1]
输出:1
示例 3:
输入:height = [4,3,2,1,4]
输出:16
示例 4:
输入:height = [1,2,1]
输出:2
提示:
n = h e i g h t . l e n g t h n = height.length n=height.length
2 ≤ n ≤ 3 ∗ 104 2 \le n \le 3 * 104 2≤n≤3∗104
0 ≤ h e i g h t [ i ] ≤ 3 ∗ 104 0 \le height[i] \le 3 * 104 0≤height[i]≤3∗104
【暴力】
【思路】
这里就是计算面积,所以两层遍历,找到面积的最大值。
【代码】
class Solution {
public:
int maxArea(vector<int>& height) {
int V=0;
for(int i=0;i<height.size()-1;i++){
for(int j=i+1;j<height.size();j++){
if((j-i)*min(height[i],height[j])>V){
V=(j-i)*min(height[i],height[j]);
}
}
}
return V;
}
};
运行结果:
超时了,输入的数组比较大。
【双指针法】
想了好久不知道怎么做,看了解答,大部分都是双指针法做的。大致的思想就是:left、right初始为左右边界,每次动一个,而且只动更短的那个,类似于木桶理论,最短的木板决定了容水量,只要移动指针,一定会使桶的底边-1,若改变长板,则容积一定会减小,但如果移动短板的指针,那么短板的长度可能会增大,容积也有可能会增大。
【代码】
下面是通过了的代码:
class Solution {
public:
int maxArea(vector<int>& height) {
int V=0;
int left=0,right=height.size()-1;
while(left<right){
if(V<(right-left)*min(height[left],height[right])){//计算容积并更新最大值
V=(right-left)*min(height[left],height[right]);
}
if(height[left]<height[right]){//左边更短
left++;
}
else{//右边更短
right--;
}
}
return V;
}
};
运行结果:
时空消耗都不是很好: