leetcode11. 盛最多水的容器

题目大意:找出两条直线,使得两条直线与水平轴构成的容器能装的水最多

题目分析:如果使用挨个遍历,枚举出所有可能的两条直线a[i],a[j],那么最大的水量就是min(a[i],a[j])*(j-i)

这种算法的时间复杂度是O(n^2),显示超时。

下面介绍一种O(n)时间复杂度的做法:

起初,用两个指针i,j分别指向最开始和最末尾的两个数值height[i],height[j].  将两者中的较小者移动,也就是说,如果height[i]>height[j],则指针j前移,否则i后移。更新移动过程中的可装水的最大值,直到i和j相遇,则移动结束。

为什么要将height[i],height[j]中的较小者移动呢?因为这样才能使得可装水的量增大。假设将两者的较大者j移动,j--,那么如果移动后height[j]>原先的height[j],则面积反而变小了(高度没变,长度变小了)。如果移动后height[j]<=height[i],则面积会更小(高度变小了,长度也变小了)。但是如果将较小者移动,那么会是什么效果呢?假设i后移,i++,若新的height[i]>原先的height[i],那么面积会增大,达到了我们的效果。

那这样做是否会有遗漏呢?假设height[0]<height[len-1],i=0,j=len-1,然后进行i++操作,那么之后就不会考虑以height[0]为左壁的容器,这样真的可以嘛?答案是可以的,因为以height[0]为左壁的容器可装水的最大容量,就是以height[0]为左壁,以height[len-1]为右壁的容器的容量,(此时的间距是最大的),容量为(len-1)*a[0]。这种情况考虑过了,所以之后就可以不用考虑height[0]了,可以放心的i++了。

代码展示:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int len = height.size();
        int max = 0;
        int temp = 0;
        for(int i=0,j=len-1;i<j;)
        {
            temp = min(height[i],height[j]);
            if((temp*(j-i))>max)
                max = temp*(j-i);
            if(height[i]>height[j])
                j--;
            else
                i++;
        }
        return max;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值