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.
SOLUTION 1:
采用2个指针一个在左一个在右,计算『桶』可以容纳的水。如果左边低,则左指针右移(试图看可不可以找到更高的bar),反之左移右指针
证明:
当H[l] < H[r]的时候,为什么可以移动左指针呢?
因为以l为边界的最大值我们已经计算出来了,它是一个短板,把r往左移不可能得到更大的蓄水量。所以以l为边界的可以结束计算了。直接把l右移即可。
引自http://www.cnblogs.com/TenosDoIt/p/3812880.html 的证明:
正确性证明:由于水的容量是有较小的那个边界决定的,因此某次迭代中,假设height[i] < height[j],那么j 减小肯定不会使水的容量增大,只有i 增加才有可能使水的容量增大。但是会不会有这种可能:当前的i 和 某个k (k > j)是最大容量, 这也是不可能的,因为按照我们的移动规则,既然右指针从k 移动到了j,说明i 的左边一定存在一个边界 m,使m > k,那么[m, k]的容量肯定大于[i, k],所以[i,k]不可能是最大容量。可以参考here
1 public class Solution { 2 public int maxArea(int[] height) { 3 if (height == null) { 4 return 0; 5 } 6 7 int left = 0; 8 int right = height.length - 1; 9 int maxArea = 0; 10 11 while (left < right) { 12 int h = Math.min(height[left], height[right]); 13 int area = h * (right - left); 14 maxArea = Math.max(maxArea, area); 15 16 if (height[left] < height[right]) { 17 // 如果左边界比较低,尝试向右寻找更高的边界 18 left++; 19 } else { 20 // 如果右边界比较低,尝试向左寻找更高的边界 21 right--; 22 } 23 } 24 25 return maxArea; 26 } 27 }
2014.1229:
1 public class Solution { 2 public int maxArea(int[] height) { 3 if (height == null) { 4 return 0; 5 } 6 7 int len = height.length; 8 int l = 0; 9 int r = len - 1; 10 11 int max = 0; 12 while (l < r) { 13 int h = Math.min(height[l], height[r]); 14 int w = r - l; 15 max = Math.max(max, h * w); 16 17 if (height[l] < height[r]) { 18 l++; 19 } else { 20 r--; 21 } 22 } 23 24 return max; 25 } 26 }
代码:
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/twoPoints/MaxArea.java