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。
题解:分别设置两个游标start和end,start从height数组的前面往后面走,end从height数组的后面往前面走。每次计算当前start和end能够形成的container的最大面积,然后将height较小的游标移动(比如如果height[start]<height[end],那么就将start往后移动一步),直到两个游标相遇,算法结束。
算法的正确性:每次移动高度较小的游标,是因为以该游标为高的最大盛水量已经计算过了。比如序列1 2 3 2 2的过程如下:
(start)1 2 3 2 2(end) answer = max(answer,1*5) = 5;此时height[start] < height[end],将start右移,因为以start=0为高的水瓶,宽度最大就是5;
1 (start)2 3 2 2(end) answer = max(answer,2*4) = 8; 此时height[start] = height[end],将start右移,因为以start=1为高的水瓶,宽度最大是4;
1 2 (start)3 2 2(end) answer = max(answer,3*3) = 9; 此时height[start] > height[end],将end左移,因为此时start左边的板高度都比end板高度低,所以此时start指向的位置就是以end为高度的水瓶宽度最远能到达的地方,即宽度最大的地方。所以以end板为高的水瓶最大的盛水量已经计算出来了,就可以把end左移了。
1 2 (start)3 2(end) 2 answer = max(answer,3*1) = 9; 此时height[start] > height[end],将end左移,start=end,循环结束。
代码如下:
1 public class Solution { 2 public int maxArea(int[] height) { 3 int start = 0 ; 4 int end = height.length-1; 5 int maximum = 0; 6 7 while(start < end){ 8 int width = end - start; 9 int h = Math.min(height[start], height[end]); 10 11 maximum = maximum > width*h?maximum:width*h; 12 13 if(height[start] > height[end]) 14 end--; 15 else { 16 start++; 17 } 18 } 19 20 return maximum; 21 } 22 }