11.盛水最多的容器

给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

img

图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例:
输入: [1,8,6,2,5,4,8,3,7]
输出: 49


果然还是我太菜,除了暴力法外,一直没想出怎样才能不漏掉最优解,直到在评论里看见了下面解释:

对O(n)的算法写一下自己的理解,一开始两个指针一个指向开头一个指向结尾,此时容器的底是最大的,接下来随着指针向内移动,会造成容器的底变小,在这种情况下想要让容器盛水变多,就只有在容器的高上下功夫。 那我们该如何决策哪个指针移动呢?我们能够发现不管是左指针向右移动一位,还是右指针向左移动一位,容器的底都是一样的,都比原来减少了 1。这种情况下我们想要让指针移动后的容器面积增大,就要使移动后的容器的高尽量大,所以我们选择指针所指的高较小的那个指针进行移动,这样我们就保留了容器较高的那条边,放弃了较小的那条边,以获得有更高的边的机会。

豁然开朗,一下问题就变简单了

class Solution {
public:
    int maxArea(vector<int>& height) {
        int max = 0, size, p1 = 0, p2 = height.size() - 1;
        while(p1 < p2){
            if(height[p1] <= height[p2])
                size = (p2 - p1)*height[p1++];
            else
                size = (p2 - p1)*height[p2--];
            max = max>size? max : size;
        }
        return max;
    }
};
posted @ 2020-02-21 21:16  马尔尤尤  阅读(103)  评论(0编辑  收藏  举报