刷题升级之路:LeetCode——11.盛最多水的容器

题目描述

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
(具体示例可以到LeetCode官网找,这里不列举出来了)

算法思路与分析

在坐标系中看比较直观可以理解,如何在所有"柱子"中选择体积最大的呢?
最朴素的想法就是两两组合全部算出来,O(n²)时间可以解决。
有什么办法可以减少冗余计算呢?(例如,不去计算那些明知道不可能的结果)
【双指针法】:在本题中其实就是从两侧的组合开始,每一步排除一个柱子,计算出当前结果,维护一个最大值。
显然地,两个柱子中较低的是“决定性因素”。
最靠边的柱子是宽最大的情况,当我们逐步减小宽度,可以发现在宽度相同(减小1)的情况下,用较低的柱子一定不会得到更好的结果,对于求最大值来说无用。所以每次去除较低的柱子,指针向内移动。表示当前两侧位置的“指针”向内趋近,直到位置重合,我们就讨论完了所有的情况,得到最大值。

代码实现

class Solution {
public:
/*
分析:容量=高×宽,高是两个边界的垂线高度较小值,宽是两个边界的距离
问题本质上是:求(i*,j*),max{min{h[i],h[j]}×(j-i)}
[朴素的想法是直接O(n²)算出每个(i,j)为边界的盛水量取最大]
那么如何减少无效计算?
【双指针法】

*/
    int maxArea(vector<int>& height) {
        int n=height.size();
        int maxx=0;
        int tmp=0;
        /*
        朴素想法:
        for(int i=0;i
        //
        int left_=0,right_=n-1;
        while(left_<right_){
            if(height[left_]<=height[right_]){
                tmp=height[left_]*(right_-left_);
                left_++;
            }
            else{
                tmp=height[right_]*(right_-left_);
                right_--;
            }
            maxx=max(maxx,tmp);
        }
        return maxx;
    }
};

你可能感兴趣的:(刷题之路,leetcode,算法)