LeetCode(11) - Container With Most Water

  这一题讲的给你一个数组height,数组上的数字代表X轴在index点上的高度,现在要求的是,取拿两个点,使两点之间能盛的水最多。我们知道,能够盛的水的高度的取决于较矮的一个的高度。假设水的容积为s,则两点之间水的容积为s = (index2 - index1) * Math.min(height[index2], height[index1])。暴力搜索O(n^2)虽然能够解决问题,但是从面试的角度这并不是面试官想要的,那么有没有更快一点O(n)的方法呢?有的。

  我们可以这么考虑,有两个指针head和tail分别指向数组的一头一尾,那么只有三种情况:

  1. height[head] < height[tail]
  2. height[head] > height[tail]
  3. 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 }
原文地址:https://www.cnblogs.com/kepuCS/p/5241454.html