LeetCode 11. Container With Most Water

问题链接

LeetCode 11. Container With Most Water

题目解析

给定坐标轴上的一些垂线段,任意两条组成“水桶”,求最大存水量。

解题思路

理解题意,任取两条线段,假设横坐标(索引)为left、right,题目要求 \((right - left) * min(H[left], H[right])\) 的最大值,即长方形面积。暴力不可取,时间复杂度将达到 \(O(n^2)\),明显不是此题的意愿。

本题采用一个巧妙的办法,左右指针分别代表所选取的两条垂直边,初始化为0和len-1。每一次比较水桶面积,通过比较 \(H[left]\)\(H[right]\) 的大小更新指针。为什么可以这样做呢?会不会漏掉一些情况而得到错误答案呢?答案是不会。类似剪枝,本方法每次剔除了一些情况,可以保证剔除的这些情况不需要考虑。举个例子,假设 \(H[left]\) 更小,我们让left++,此时剔除的情况有哪些呢?剔除了选取原来的 \(left\) 位置与 \(left+1~right\) 位置组成的“水桶”,这些水桶的面积不可能比当前水桶(left,right)大,因为水桶的底在变小,高不可能会超过 \(H[left]\),面积自然不可能变大。

参考代码

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

官方答案

官方链接:https://leetcode.com/problems/container-with-most-water/solution/

答案中也是提到暴力和指针两种方法,不过有视频展示过程,更容易理解,简单看看。

指针方法还有可以改进的地方,在相邻位置相等时直接跳过,节省一点点时间。可参考https://leetcode.com/problems/container-with-most-water/discuss/6090/Simple-and-fast-C++C-with-explanation


LeetCode All in One题解汇总(持续更新中...)

本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


posted @ 2018-03-13 12:08  AlvinZH  阅读(542)  评论(0编辑  收藏  举报