题目:盛最多水的容器
描述:
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
实例一:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
leetcode链接
方法一:双指针法
同样此题目可以用两个for循环暴力解,时间复杂度为o(n²),但是经过测试时间超限,那么我们考虑优化时间复杂度。为
我们定义两个指针left和right分别指向数组的头部和尾部,此时我们的容积为(right-left)*min(height[left],height[right]),即为长方形的长×高,我们维护一个容积变量maxVal始终存储最大值,那么下一步我们应该移动哪一个指针呢,我们考虑如下情况:
1.我们移动指向数较大的指针,首先不管我们怎么移动我们长方形的长都会变小,而我们移动指向数较大的指针,出现的结果又会有2种,第一种为指向一个更大的数,而我们长方形的高由小的数决定,因此我们长方形的高不变,总面积减小,第二种为指向一个更小的数,此时我们长方形的高变小,总面积变小,综上,我们移动指向数较大的指针,无论怎么样,我们的长方形的面积总会减小,因此我们的容积也会减小,所以移动指向较大的数字的指针不可行
2.我们移动指向数较小的指针,当移动后指向了一个更大的数时,我们长方形的高变大,宽变小,此时我们长方形的面积才有可能变大,所以移动指向数较小的指针可行。
综上所述,我们移动指向数较小的指针才有可能找到更大面积的长方形,所以我们每次移动后去维护容积变量为最大的长方形的面积。
时间复杂度:o(n) 只需要遍历一遍数组
空间复杂度:o(1)
int maxArea(vector<int>& height) {
int n = height.size();
int left = 0,right = n-1;
int maxVal = 0;//最大的容积
while(left<right){
maxVal = max(maxVal,(right-left)*min(height[left],height[right]));
if(height[left]<height[right]){//较小的指针移动
left++;
}else{
right--;
}
}
return maxVal;
}