leetcode_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.
题解:题目意思是找出两个点 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<aj ,面积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:


浙公网安备 33010602011771号