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

来源:互联网 发布:萨洛蒙鞋怎么样知乎 编辑:程序博客网 时间:2024/06/09 21:59

题目:
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.
这里写图片描述
这个题目与上面的题目有一点点不一样,其实思路也类似,也可以首先根据2端确定一个容器的高度,求出该容器高度所能装的水,可以用2个指针,以上面的图为例:
第一次求下图所能容纳的水的体积:
这里写图片描述
第2次,再求下图水的体积:
这里写图片描述
这样的话思路就很简单了,总的时间复杂度也是O(n).

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