leetcode-11 Container With Most Water

题目简单。

最简单的办法,就是从第一个开始,依次两两计算,求得最大值即可。

最简单的思路,往往也意味着是最笨的方法,很明显,这样的计算量大,果然,提交代码,超时。

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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值