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.分析
题目很清楚就不解释了。给出一组数组,元素值代表木头的高度,两个元素值只差代表水桶的宽度,装水的容量是短板效应,即容量取决于短的那根木头以及桶的宽度。
所以容量的计算公式为:min(height[left],height[right]) * (right - left)算法
这道题一开始我没想到好办法,就打算用暴力求解,穷举各种可能性,所以时间复杂度为O(n^2),超时了。没办法,想也想不出好办法,就搜了一下,发现另外一个办法是如此简单,时间复杂度是O(n):
原文在这里
思路在代码注释中给出代码
//穷举法
public class Solution {
public int maxArea(int[] height) {
int maxarea = 0;
for (int i = 0; i < height.length; i++)
for (int j = i + 1; j < height.length; j++)
maxarea = Math.max(maxarea, Math.min(height[i], height[j]) * (j - i));
return maxarea;
}
}
//两个指针靠拢法
public class Solution {
public int maxArea(int[] height) {
int left = 0,right = height.length -1;//左右两颗指针
int max = 0;//保存最大值
while(left < right){
int c = Math.min(height[left],height[right]) * (right - left);//计算容量
if(c>max){
max = c;
}
//如果左边的高度小于右边的高度
//如果想要容量增大,那么必须把左边的增高(短板效应,
//移动右边的是没有用的,因为高度是取短的那个)
//所以left向右移动,直到遇到更高的才从新计算容量
if(height[left] <height[right]){
int l = height[left];
do{
left ++;
}while(left < right && height[left] < l);
}else{//右边的同理 向左移动
int r = height[right];
do{
right--;
}while(left < right && height[right] < r);
}
}
return max;
}
}