这一题讲的给你一个数组height,数组上的数字代表X轴在index点上的高度,现在要求的是,取拿两个点,使两点之间能盛的水最多。我们知道,能够盛的水的高度的取决于较矮的一个的高度。假设水的容积为s,则两点之间水的容积为s = (index2 - index1) * Math.min(height[index2], height[index1])。暴力搜索O(n^2)虽然能够解决问题,但是从面试的角度这并不是面试官想要的,那么有没有更快一点O(n)的方法呢?有的。
我们可以这么考虑,有两个指针head和tail分别指向数组的一头一尾,那么只有三种情况:
- height[head] < height[tail]
- height[head] > height[tail]
- height[head] = height[tail]
第一种和第二种情况是相同的,当第一种情况时,我们发现,对于head来说,s(head) = height[head] * (tail - head)已经达到最大,以height[head]这个高度的容积不可能还有比它更大的情况(tail - head最大),所以我们就当作是遍历过head这个点,得到以它这个高度的最大值,因而head = head + 1往下走。对于第二种情况也是类似,那就是tail = tail - 1。如果是第三种情况呢?随便移动一个就好(其实两个同时移动也没有关系,影响的也只是比height[head]小的高度的最大值,不可能比height[head]的最大值要大)。整个过程维护一个最大值max就好。
代码如下:
1 //two pointer.两个指针一前一后,高度小的那个挪动。(因为高度小的那个的面积已达到最大)。 2 public class Solution { 3 public int maxArea(int[] height) { 4 int length = height.length; 5 if (length == 0) return 0; 6 int head = 0, tail = length - 1; 7 int max = 0; 8 while (head < tail) { 9 if (height[head] <= height[tail]) { 10 int contain = (tail - head) * height[head]; 11 if (contain > max) max = contain; 12 head++; 13 } 14 else { 15 int contain = (tail - head) * height[tail]; 16 if (contain > max) max = contain; 17 tail--; 18 } 19 } 20 return max; 21 22 } 23 }