LeetCode题解(Week 1):Container With Most Water

本文探讨了LeetCode上一道经典题目——盛水最多的容器的高效解决方案。介绍了一种从两端向中间逼近的方法,避免了传统双层循环的高时间复杂度问题,实现了O(n)的算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题目

Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.

Subscribe to see which companies asked this question.

题目中文大意

给定n个非负整数a1,a2, …, an,其中ai可以作为第i个位置的木板高度,求在这么多个位置的木板中,找到两块木板,构成的水桶,盛到的水最多,并返回对应的水量。

思路

  1. 给定两个木板ai,aj(j>i),他们围成的木桶,装水量为min(ai,aj)*(j-i),水量的计算方式,这构成了本题的基础。可知,水量大小取决于两个模板的间隔以及最短的木板。
  2. 在这种情况下,最直接的做法是,用二层循环,将每一对木板都遍历一遍,求出对应的面积,通过比较求得最大水量。然而,这种方法的时间复杂度为O(n^2),超出了时间限制。
  3. 为了更加便捷地求出最大的出水量,可以从两头到中间进行遍历,但问题在于,在什么情况下,缩小木板的跨度。
  4. left,right分别为最左边,最右边的木板对应的下标,假设当前遍历到a[left],a[right], 假设较小的是a[left],那这时候如果要缩小跨度,应该从left端入手(将短木板换成长木板,才有可能取得更大的水量),因此left向右递增。
  5. 这样的遍历直到left==right终止。这样,最终的算法复杂度是O(n),不会超时

题解(O(n))

class Solution {
public:
    int maxArea(vector<int>& height) 
    {
        int n = height.size();
        int left = 0;
        int right = n-1;
        int mostWater = -1;
        while(left!=right)
        {
            int currWater;
            if(height[left] > height[right])
            {
                currWater = height[right] * (right-left);
                right--;
                // if(height[right] < height[right+1])
                //     right --;
            }
            else
            {
                currWater = height[left] * (right-left);
                left ++;
                // if(height[left] < height[left-1])
                //     left++;
            }
            if(currWater > mostWater) mostWater = currWater;
        }
        return mostWater;
    }
};

心得体会

在本周的leetcode中,一种很常见的做法是用两个下标来遍历数组,从而达到降低算法的时间复杂度的目的(比如之前的快慢指针,这道题的从左右到中间的遍历)。这种方法值得在日后的题目中使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值