力扣11-盛水最多的容器

本来今天是想学习“贪心算法”,打算找两个题来边学边做。
然后精挑细选选了这题,本来冲着“贪婪”去,瞟一眼题就打算去看题解,然后题解说:最优解是双指针。
啊双指针我会啊,我真蠢😂居然没看出来。然后就写,感觉多简单的

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

再然后就超时了😂时间复杂度达到了O(N2),果然就这么过了它就不配是中等题,肯定是有什么优化的办法。
然后我去看了题解,只有一个双指针解法…所以这跟贪心有什么关系???

题解

官方题解采用的虽然也是双指针,但是不同于我原始的“同向不同初值”,而是采用了“两头往中间靠”的方式。并且根据核心的公式代码
maxA = max(maxA,(j-i)*min(height[i],height[j]));
可以发现,要使乘积最大,即使height[]中的较小值变大乘积才有可能增加;与此同时,(j-i)是注定变小的
……试一试先
image

class Solution {
public:
    int maxArea(vector<int>& height) {
    int l = 0, r = height.size()-1;
    int maxA = 0;

    while (l <= r)
    {
        maxA = max(maxA, (r - l) * min(height[r], height[l]));
        if (height[l] < height[r])
        {
            ++l;
        }
        else
        {
            --r;
        }
    }        
        return maxA;
    }
};

时间复杂度O(n),遍历一次数组;空间复杂度O(1),但看起来还是很差

那么,为什么这样是正确的,其实每一次移动并不保证乘积一定会变大,但是有这种可能,并且最终结果是包含在这些可能之中,的吧。

posted @ 2022-04-15 09:40  YaosGHC  阅读(32)  评论(0)    收藏  举报