11. Container With Most Water

本文介绍了一种利用双指针技巧解决寻找两个线段形成的最大容器问题的算法。通过从两端向内移动指针,每次移动高度较小的线段对应的指针,确保不会错过最大容器的可能组合。

题意

给定n个非负整数a1,a2,…,an,其中每个代表一个点坐标(i,ai)。n个垂直线段例如线段的两个端点在(i,ai)和(i,0)。找到两个线段,与x轴形成一个容器,使其包含最多的水。

思路

首先,任何情况下必然存在一个最优解,即一对线段形成包含最多水的容器。问题在于如何找到这一对线段。

可以设置两根指针,分别指向第一个线段和最后一个线段,不断的向内移动,在移动的过程中,如果能途径这一对最优解线段,记录下此时的容量,也就完成了任务。

那么通过怎样的方法向内移动才能途径这一对最优解线段呢?

为了不错过最优解,每一次移动,我们要选择收益最大的方向去移动,使用贪心的思想。每次,如果我们移动指向高度更小的线段的指针,那么就不可能错过这一对最优解线段。因为移动指向高度更小的线段的指针一定给我们带来更大的收益。原因在于容量的大小在于更短一根线段的高度。所以,只有移动指向高度更小的线段的指针,才有可能使得下一步的容量增加,如果移动另一个指针,一定不可能使得容量增加。因为这样移动就算移动到长度更大的一个线段上,由于底部长度变小,容器有效高度不变,容量必然减小。

明白了以上这点,请看下面的证明。
在这里插入图片描述

代码

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

参考

证明出处:https://segmentfault.com/a/1190000008824222#articleHeader2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值