题目简单。
最简单的办法,就是从第一个开始,依次两两计算,求得最大值即可。
最简单的思路,往往也意味着是最笨的方法,很明显,这样的计算量大,果然,提交代码,超时。
for(i=0; i != num-1; ++i)
{
for(j=1; j != num; ++j)
{
max = max > (j-i)*(height[i] > height[j] ? height[j] : height[i]) ? max : (j-i)*(height[i] > height[j] ? height[j] : height[i]);
}
}
如何减少计算?
通过观察可以发现,由于题目类似计算最大的矩形面积,也就是长和宽尽可能得大。
首先,两边值为边界值,那么很明显,a1和an之间的ai,只要ai小于边界,就直接排除。
其次,可以计算出最大值a-max,以最大值为中界,最大面积的矩形的左边界不会超过a-max的右边,矩形的右边界也不会超过最大值的左边。因此,可以从两头开始,朝中间靠拢。
再次,发现,从两头向中间靠拢时,以左边为例,假设maxL为左边已经计算过的height[i]的最大值,当下一个height[i]<=maxL时,可以直接跳过,因为其计算的值,必然小于之前maxL处。右边也同理可得。
如图所示,共有9个数,其中最大为a6,所以,最大面积的矩形的左边界在a1~a6之间,右边界在a6~a9之间。
但是注意边界值a6的取值要特别小心,两个边界不能同时为a6!
分别以maxL、maxR代表左边和右边的局部最大值。
很明显的,a2,a4, 都 小于a1,所以,直接跳过,以后类似处理,减少计算。
最后,代码如下:
class Solution {
public:
int maxArea(vector<int>& height) {
int num = height.size();//ai总的数目
int max=0;//最大面积
int i,j;
int maxHeight=height[0];//最大ai
//首先计算出ai最大值,并记录位置count
int count=0;
for(i=1; i != num; ++i)
{
if(maxHeight < height[i])
{
maxHeight = height[i];
count = i;
}
}
int maxL=height[0];//表示从a1到maxHeight之间的较大值,用于减少计算的目的,当碰到ai比maxL小的时候,就直接跳过
int maxR=height[num-1];
//计算最大值
for(i=0; i <= count; ++i)
{
if(height[i] <= maxL && i != 0 )//跳过maxHeight之前比边界小的值
continue;
maxL = height[i];
//内部循环从maxHeight开始
for(j=num-1; j >= count; --j)
{
if(height[j] <= maxR && j != num-1 )
continue;
if( i == j)
continue;
maxR = height[j];
max = max > (j-i)*(height[i] > height[j] ? height[j] : height[i]) ? max : (j-i)*(height[i] > height[j] ? height[j] : height[i]);
}
}
return max;
}
};