P108. 雨后盛水量

leetcode 42 lintcode 363 数组 双指针 免费 讨论

温馨提示:如果题目对您来说比较简单,可以采用 1.5 倍速观看。 立即注册观看更多视频

描述

这个题目说的是,给你一个非负整数数组表示的高度图,你要计算出下雨后,这个高度图中可以盛多少水。

比如说,给你的数组是:

0, 2, 0, 4, 0, 1, 2

高度示意图:

  ^
  |
4 +        +--+
  |        |  |
3 +        |  |
  |        |  |
2 +  +--+  |  |     +--+
  |  |  |  |  |     |  |
1 +  |  |  |  |  +--+  |
  |  |  |  |  |  |  |  |
  +--+--+--+--+--+--+--+-->
   0  1  2  3  4  5  6

在这个高度图中,下标 2 位置的盛水量是 2,下标 4 位置的盛水量是 2,下标 5 位置的盛水量是 1,因此总共的盛水量是:

2 + 2 + 1 = 5
代码
public class AlgoCasts {

  // Time: O(n), Space: O(n)
  public int waterCanBeTrap(int[] height) {
    if (height == null || height.length == 0) return 0;
    int n = height.length, leftMax = -1, rightMax = -1, water = 0;
    int[] d = new int[n];
    for (int i = 0; i < n; ++i) {
      leftMax = Math.max(leftMax, height[i]);
      d[i] = leftMax;
    }
    for (int i = n-1; i >= 0; --i) {
      rightMax = Math.max(rightMax, height[i]);
      d[i] = Math.min(d[i], rightMax);
      water += (d[i] - height[i]);
    }
    return water;
  }

  // Time: O(n), Space: O(1)
  public int waterCanBeTrapO1(int[] height) {
    if (height == null || height.length == 0) return 0;
    int leftMax = -1, rightMax = -1, water = 0;
    int i = 0, j = height.length - 1;
    while (i <= j) {
      leftMax = Math.max(leftMax, height[i]);
      rightMax = Math.max(rightMax, height[j]);
      if (leftMax < rightMax) water += (leftMax - height[i++]);
      else water += (rightMax - height[j--]);
    }
    return water;
  }

}

关于 AlgoCasts

AlgoCasts 旨在用心做好每一个算法讲解视频。每个视频包含两个部分:题目的剖析讲解以及编码,力求在讲解清楚到位的基础上,尽可能地保持视频精简短小,让大家可以在碎片时间里进行学习,并收获这些算法题背后的思想与乐趣。