leetcode题解系列-010 盛最多水的容器

题目

leetcode题解系列-010 盛最多水的容器_第1张图片

 

老规矩先上代码,后面有解题思路。

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

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

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

示例:

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

#include 
#include 

using std::vector;

class Solution {
public:
    int maxArea(vector& height) {
        int ret{0};
        for (auto beg = height.begin(), end = std::prev(height.end()); beg < end; *beg < *end ? ++beg : --end)
            ret = std::max(ret, static_cast(end - beg) * std::min(*beg, *end));
        return ret;
    }
};

int main(int argc, char **argv)
{
    Solution s;
    std::vector test = {1,8,6,2,5,4,8,3,7};

    std::cout << s.maxArea(test) << std::endl;

    return 0;
}

解题思路

这道题着实想了好一阵子。


首先难在理解题意,这个返回值到底代表什么含义?
我开始总以为是相邻的两个line组成的水池,根据短板效应,也就成了类似找最大值的问题。后来察觉到不对,才发现题目并没有说什么相邻。恍然大悟,应该是求任意两条线形成大最大面积。
这该怎么解决?再长的线如果距离不够长,那也是白搭。如何能够综合考虑?
已经很晚的时候,我才灵机一动,如果从最长距离开始呢?左边是beg,右边是end,然后总体向里挪动。在挪动过程中不断比较,记住最大值。
但问题的关键在于怎么移动?
我开始想岔了,总想着要有最大面积的话,需要更长的边才行,于是觉得应该分别与里面的边比,如果遇到更长的,才往里挪动。结果发现这样根本挪不动。谁也无法保证里面就会比外面长。能比的只有 beg 和 end 这两个边。谁小,谁就应该往里面挪动。
这样,几乎就不会有什么遗漏的面积了。
于是,最后一个循环就搞定了,代码异常的简洁。

最后附上网上大神的解法,这个解法我个人确实没想到,仅供给大家参考:

时间复杂度O(n),两个指针i, j分别从前后向中间移动,两个指针分别表示容器的左右边界。每次迭代用当前的容量更新最大容量,然后把高度小的边界对应的指针往中间移动一位。 本文地址

正确性证明:由于水的容量是有较小的那个边界决定的,因此某次迭代中,假设height[i] < height[j],那么j 减小肯定不会使水的容量增大,只有i 增加才有可能使水的容量增大。但是会不会有这种可能:当前的i 和 某个k (k > j)是最大容量, 这也是不可能的,因为按照我们的移动规则,既然右指针从k 移动到了j,说明i 的左边一定存在一个边界 m,使m > k,那么[m, k]的容量肯定大于[i, k],所以[i,k]不可能是最大容量。

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

你可能感兴趣的:(leetcode题解系列)