leetcode_Container With Most Water

题目:Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) 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.

题解:题目意思是找出两个点 i 和 j ,使得过(i,0)与(i,ai)的直线,过(j,0)与(j,aj)的直线,x轴三条直线围城的容器装的水最多。如下图为直线x=1,x=n与x轴围成的容器,绿色部分表示能装的最多的水(注意容器不可倾斜);

 

可以看出装的水就是求面积,area=(n-1)*min(a1,an);

由此可以用最为简单粗暴的方式破解,类似冒泡排序,依次选取两个点,比较其面积,每次比较保留较大值;循环结束必定可以得出全局最大;复杂度达O(n2).

 代码如下:

int min(int a,int b)
{
    return a<b?a:b;
}
int maxArea(int* height, int heightSize) {
    int max=0;
    for(int i=0;i<heightSize-1;i++)
    {
        for(int j=i+1;j<heightSize;j++)
        {
            int temp=(j-i)*min(height[i],height[j]);
            if(temp>max)max=temp;
        }
    }
    return max;
}

 但是:真这么简单就算是简单题而不是中等题了,上述算法效率低下,数据一大必定超时......

所以必定是要改进算法,怎么改进?最重要就是分析上述算法中哪些比较是多余的。如下图:

 

①当ai<a,面积area=(j-i)*ai ,并且i到i+1,i+2,......,j-1的点围城的面积都一定比这个面积小。属于多余的比较;此时i++;

②反之ai>aj,面积area=(j-i)*aj, 并且i+1,i+2,......,j-1分别与j围城的面积必定小于这个面积。也属于多余的比较;此时j--;

算法直到i==j结束;

此算法将复杂度减少到O(n),代码如下:

 

int min(int a,int b)
{
    return a<b?a:b;
}
int maxArea(int* height, int heightSize) {
    int i=1,j=heightSize;
    int max=0;
    while(i!=j)
    {
        int temp=(j-i)*min(height[i-1],height[j-1]);
        if(temp>max)max=temp;
        if(height[i-1]>height[j-1])j--;
        else i++;
    }
    return max;
}

 

运行时间8ms:

 
 

 

posted @ 2016-03-29 14:20  强子GOR  阅读(133)  评论(0)    收藏  举报