题目简析:这题目我觉得是蛮坑爹的,因为题目的语境要求使得“容器”最大,但是类名却是maxarea,以及想破头脑都想不出两条线如何跟x轴组成容器,经过思考,我觉得这个模型应该是省略容器底部的宽(或者长),假设其为一个缺省值,那么问题的重心就从体积这个问题转化到求侧面积——即长乘高(或宽乘高),加上最后一句不能倾斜的提醒,自然是木桶效应,即指a1、a2之最小者将限制木桶高度,用图拍表示就是
这个底部宽度值x值假设为缺省值,那么问题就简化成再i-a平面中找出最大矩形面积的问题了,即如下图:
最简单的方式就是进行一次二阶遍历,复杂度O(n²),但是显然超时,因此我们可以采取贪心算法。我们先取最大的底长——即n,a0或者an的最小值作为高,得到第一个maxarea,接着我们让较短边(假设是a0边),不断往右移动,直至找到一条比a0高的边ak,那么我们就有了一个比原来更大的高(也许是ak也许是an,取两者较小值),虽然此时底长n减少为n-k,但是我们重新计算此时的面积,看能否找到比原来更大的maxarea,如此这般,最多只要O(n)的复杂度即可完成遍历
因此我们可以设置left和right两个标记,分别从两端,每次取长度低者,将标记往中间靠拢以获取一个比原来的高度,并更新maxarea。
以下贴上代码
class Solution {
public:
int maxArea(vector<int>& height) {
int left=0;
int right=height.size()-1;
int max;
int temparea;
if(height[left]<=height[right])
max=(right-left)*height[left];
else
max=(right-left)*height[right];
int i,j;
while(right>left){
if(height[left]<=height[right]){
for(i=left;i<right;i++){
if(height[i]>height[left])
break;
}
left=i;
}
else{
for(j=right;j>left;j--){
if(height[j]>height[right])
break;
}
right=j;
}
if(height[left]<=height[right])
temparea=height[left]*(right-left);
else
temparea=height[right]*(right-left);
if(temparea>max)
max = temparea;
}
return max;
}
};
Submission Result: Accepted
Runtime: 0 ms
题目链接:https://leetcode.com/problems/container-with-most-water/description/