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.
Subscribe to see which companies asked this question
这个题目的意思可能不是很好懂,这个题的意思是给一个整数的数组,例如【0,1,4,5,2,6】 0代表直线的高度是0,1代表高度是1……两个数字坐标的相对位置代表的是宽度,高度和宽度组成一个木桶,求给定数组所有木桶组合能盛放的最多的水的面积。
以上一个数组中的4和6为例:
4和6 中相对最小的数字【4】代表高度【木桶原理】
4和6的相对位置【5-2】代表宽度,那么这个组合的容积就应该是
4*3=12
求出最大的容积。
第一种也是最好想到的方法双层循环穷举所有组合,返回最大即可,java代码如下:
public static int maxArea(int[] height) {
int max =0;
for(int i=0;i<height.length;i++){
for(int j=i;j<height.length;j++){
int maxHeight=
height[i]>height[j]?height[j]:height[i];
if(maxHeight*(j-i)>max){
max = maxHeight*(j-i);
System.err.println(j + ":" +i);
}
}
}
return max;
}
这种解法无疑是正确的,但是无疑也是最低效的,时间复杂度达到O(n2),提交也被驳回,理由是时间不能接受。
那么有没有o(n)的解法呢?答案是有的,定义两个指针,从两边向中间移动,low high,如果high处的高度大于low,则low+1,反之则high-1, java代码如下:
public static int maxArea1(int[] height) {
if (height.length < 2) return 0;
int max =0;
int low =0;
int high=height.length-1;
while(high>low){
int maxHight = height[high]>height[low]?height[low]:height[high];
if(maxHight*(high-low)>max){
max =maxHight*(high-low);
}
if(height[high]>height[low]) low++; else high--;
}
return max;
}
时间复杂度为 O(n)