[array] leetCode-11. Container With Most Water-Medium

时间:2022-12-29 14:03:22

leetCode-11. Container With Most Water-Medium

descrition

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.

解析

方法 1:

暴力法,双重循环检查每一对可能候选 min(a[i], a[j])*abs(j-i),保留最大值,即为面积最大的方案。时间复杂度-O(n^2),空间复杂度-O(1)

方法 2:

时间复杂度-O(n),空间复杂度-O(1)。

对于任意一个候选,面积的计算为:min(a[i], a[j])*abs(j-i),i!=j。两个竖直线的间距 abs(j-i) 越大,面积就会越大,同时矩形面积的大小取决于 a[i], a[j] 中较短的边。
这时我们使用两个指针 ileft,iright 分别从左至右,从右至左遍历数组,直到两则重合停止。这时巨星面积为:area=min(a[ileft], a[iright])*(iright-ileft),使用 maxarea 记录当前最大的面积。一方面,初始时 ileft = 0, iright = n,(iright-ileft) 这一项最大,当两个指针不断往中间靠拢时,间距会逐渐减小;另一方面,面积取决于 a[ileft], a[iright] 较短的边,不是一般性假设 a[ileft] < a[iright],此时如果我们将 iright 往左移,面积将取决于较短的边,area 有可能不会增大,如果我们将 ileft 往右移,将有可能增大 area,因为当前 a[ileft] 是限制面积增长的关键。

leetcode-solution 很好的解释,通过动态规划的思想(类似最短路径的求解思想),或反证法可以证明算法的正确性。

code


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution{
public:
    int maxArea(vector<int>& height){
        int maximum = 0;
        int ileft = 0, iright = height.size() - 1;
        while(ileft < iright){
            int area = min(height[iright], height[ileft]) * (iright - ileft);
            maximum = max(area, maximum);
            if(height[ileft] < height[iright])
                ileft++;
            else
                iright--;
        }

        return maximum;
    }
};

int main()
{
    return 0;
}