Leetcode 11 -- 双指针&&贪心

题目说明

盛水最多的容器
题目要求我们找出两个边界 LR,使得 容量:min(right[L],right[R])(RL) 的值最大。

思路

算法不是玄学。
首先,两层 for 循环暴力枚举所有情况肯定是对的。(不要觉得暴力是没用的,很多情况下,只有证明优化过的算法和暴力可以达到同样的效果,才能保证这个算法是正确的)当然,暴力肯定会超时。
我们可以考虑双指针,两个指针一个指向左边界 L,一个指向右边界 R,从这个水桶的外侧往内逐渐压缩。
现在,有一个难题,我们的指针肯定要往内移动,问题是,该如何移动?是两个指针同时往内移动,还是左指针向右移动,还是右指针向左移动?
为了确保答案的正确性,我们要保证移动的过程中不要漏掉最优解。所以在这三种情况中,第一种情况肯定是不行的。那么就剩下移动左指针还是右指针了。
结论:如果一个边界的高度太低,那么此时,它已经得到了它能构成的最大值!
证明:假设左边界的高度小于右边界,我们移动右边界而不是左边界(高度低的一方)
因为我们的指针不能向外移动,所以 (RL) 的值肯定是随着 R 向内走而减小的。那么此时左右边界构成的值就由 min(height[L],height[R]) 决定了,又因为这是取最小值,所以这个值是肯定不会增大的。所以说,当左边界的高度小于右边界时,移动右边界,得到的容量绝对不会变大。也就是说其中绝对不会包含比此时更优的解。当左边界的高度大于右边界时同理。于是,我们就可以确保,这样的方案符合暴力得到的解。

代码

class Solution {
public:
    int maxArea(vector<int>& height) {
        int n = height.size();
        
        int left = 0, right = n - 1, f = 1, res = 0;
        while(left < right)
        {
            res = max(res, (right - left) * min(height[left], height[right]));
            if(height[left] < height[right])    left ++ ;
            else    right -- ;
        }
        // 算法不是玄学,我们要考虑,为什么双指针是正确的。
        return res;
    }
};
posted @   光風霽月  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示