LeetCode 11 Container With Most Water算法分析及其变体

题目:
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.
题意:在二维坐标系中,(i, ai) 表示 从 (i, 0) 到 (i, ai) 的一条线段,任意两条这样的线段和 x 轴组成一个木桶,找出能够盛水最多的木桶,返回其容积。

分析:最简单的思路就是2层for循环暴力求解,但是这种方式效率太低,当数组很大的时候会超时。那有没有更好的方法呢?
我们可以利用木桶的性质, 装水的容积=2端最小高度*宽度, 那么我们首先用2端的线段(宽度最宽),及其确定的容器高度得到一个容器, 那么如果存在容器比这个容量高,那么该容器的高度显然要比初始容器的高度高,这样分析后就很容易了,可以通过首尾2个指针,首指针后移(如果其对应的高度小于或等于前面容器确定的高度,就一直循环右移),尾指针左移动,方法同理,这样下来,整体的时间复杂度是O(n).

int maxArea(vector<int>& height) 
{
    int water = 0;
    int i = 0, j = height.size() - 1;
    while (i < j)
    {
        int h = min(height[i], height[j]);
        water = max(water, (j - i) * h);
        while (height[i] <= h && i < j) 
            i++;
        while (height[j] <= h && i < j) 
            j--;
    }
    return water;
}

这道算法的变体 leetcode 42 Tapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
LeetCode 11 Container With Most Water算法分析及其变体_第1张图片
这个题目与上面的题目有一点点不一样,其实思路也类似,也可以首先根据2端确定一个容器的高度,求出该容器高度所能装的水,可以用2个指针,以上面的图为例:
第一次求下图所能容纳的水的体积:
LeetCode 11 Container With Most Water算法分析及其变体_第2张图片
第2次,再求下图水的体积:
LeetCode 11 Container With Most Water算法分析及其变体_第3张图片
这样的话思路就很简单了,总的时间复杂度也是O(n).

int trap(vector<int>& height) 
{
    int water=0,i=0,j=height.size()-1,t=0,min1=0;
    while(iint minHeight=min(height[i],height[j]);
        for(t=i+1;tif(height[t]if(height[t]>=min1)
                    water+=minHeight-height[t];
                else
                    water+=minHeight-min1;
            }
        }
        while(iwhile(ireturn water;
}

你可能感兴趣的:(编程与算法,leetcode,算法)