11. Container With Most WaterGiven
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,j,分别从两边往中间移动。因为高度取决于最短的板,又因为越往中间走的话,距离变短,所以只能找板高度更高的板来平衡,所以当height[i] < height[j]时,如果j减小,无论height[j]的高度大还是小,都比现状面积小(如果height[j]变小,height[i] > height[j];如果height[j]变大,最短板仍取决于height[i]),而且距离更短了,所以可跳过计算,只能是i++;同理,当height[i] > height[j]时,j- -,然后判断面积是否更大。
public class Solution {
public int maxArea(int[] height) {
int mxArea = 0;
int left = 0, right = height.length - 1;
while(left<right) {
int curArea = Math.min(height[left], height[right]) * (right-left);
mxArea = Math.max(curArea,mxArea);
// 如果左边数比右边数小
if(height[left] < height[right]) {
left++;
// 如果左边数比右边数大
} else {
right--;
}
}
return mxArea;
}
}
解法二
在解法一的基础上,i++时,当遇到比height[i]更低的板,面积会更小,同理,j- -时,遇到比height[j]更低的板,面积也会更小,所以可以直接跳过,省去计算。
public class Solution {
public int maxArea(int[] height) {
int mxArea = 0;
int left = 0, right = height.length - 1;
int flag_left, flag_right;
while(left < right) {
int curArea = Math.min(height[left], height[right]) * (right-left);
mxArea = Math.max(curArea, mxArea);
if(height[left] < height[right]) {
flag_left = height[left++];
// 如果比height[left]小,跳过
while (height[left] < flag_left && left < right) {
left++;
}
} else {
flag_right = height[right--];
// 如果比height[right]小,跳过
while (height[right] < flag_right && left < right) {
right--;
}
}
}
return mxArea;
}
}