leetcode(11)盛最多水的容器

8 篇文章 0 订阅

题目链接:盛最多水的容器

拿到这个题目,结合示意图看了下,基本上就是一个给定一组宽,高,求最大面积的题目, 同时很容易让人想到“木桶原理”,即,最短的那块板决定木桶的容量。

题目给出了一个数组,里面存放所有的高度值,宽度值可以通过计算数组索引的差得到,因此任意两个值之间面积值为:

const index1,index2;//	数组索引,index2 大于 index1
const int height1 = heightArray[index1];
const int height2 = heightArray[index2];
const int height = height1 > height2 ? height2 : height1;
const int width =  index2 - index1;
const int area = width * height;

面积的计算方式有了,接下来就是遍历所有的情况计算最大值,常规的遍历方式如下:

在这里插入图片描述

为了后面描述方便假设索引所对应的值为v0,v1,v2,v3,v4,v5,v6

区间面积表示为area[index1, index2]

横轴代表数组索引,纵轴代表索引所对应的值,从索引0开始,分别计算[0,1],[0,2],[0,3],[0,4],[0,5],[0,6]这六个区间的面积,找到最大的面积,然后再从索引1开始,计算[1,2],[1,3],[1,4],[1,5],[1,6],以此类推计算所有情况的值,找到最大的那一个。

常规的遍历方式需要计算每种情况的值,实际上可以通过一些规律避免每种情况都去计算。

比如从索引0开始,计算面积的时候,先计算[0,6],再计算[0,5],[0,4],[0,3],[0,2],[0,1],以这种顺序计算。这样当索引递减时,宽度值也在递减,因此,计算完[0,6]再去计算[0,5]的时候,如果v5 <= v6,则area[0,5]必然小于area[0,6],通过这样的判断就可以不去计算[0,5]这个区间。后面继续按照这种方式处理[0,4],[0,3],[0,2],[0,1]。

结合上面示例图的情况就是:

[0,6] 需要计算

[0,5] 需要计算 (由于v5 > v6,记录最大值 maxHeight = v5)

[0,4] 不计算 (由于v4 < maxHeight )

[0,3] 需要计算(由于v3 > maxHeight,记录最大值maxHeight = v3)

[0,2] 不计算 (由于v2 < maxHeight)

[0,1] 不计算 (由于v1 < maxHeight)

下面是C++版的具体实现算法:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int maxValue = 0;
        const int vecLength = height.size();
        int leftMaxValue = 0;
        for(int i = 0; i < vecLength; i++)
        {
            const int leftValue = height[i];
            if(leftValue > leftMaxValue)
            {
                leftMaxValue = leftValue;
                int rightMaxHeight = 0;
                int lastIndex = vecLength - 1;
                while(lastIndex > i)
                {
                    int rightValue = height[lastIndex];
                    if(rightValue > rightMaxHeight)
                    {
                        rightMaxHeight = rightValue;
                        const int width = lastIndex - i;
                        const int minHeight = rightValue > leftValue ? leftValue : rightValue;
                        const int value = minHeight * width;
                        if(value > maxValue)
                        {
                            maxValue = value;
                        }
                    }
                    lastIndex--;
                }
            }
        }
        return maxValue;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值