[LeetCode][DP] Trapping Rain Water

Problem

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

[LeetCode][DP] Trapping Rain Water_第1张图片
Water

The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.

Solution

用两个数组,维护从左边到当前的元素最大高度,另外一个是从右边到当前元素的最大高度。当前元素的积水高度就取决于左右两边的较小值 - 当前元素高度。

Swift

class Solution {
  func trap(height: [Int]) -> Int {
    if height.count == 0 {
      return 0
    }
    var leftMax: [Int] = []
    var rightMax: [Int] = []
    var maxH = -1
    for h in height {
      leftMax.append(maxH)
      maxH = max(maxH, h)
    }
    maxH = -1
    for h in height.reverse() {
      rightMax.insert(maxH, atIndex: 0)
      maxH = max(maxH, h)
    }
    
    var ret : Int = 0
    for i in 0..

另一种思路:Time: O(n), Space: O(1)
维护左右两个指针,然后朝里推进。于此同时,维护左右两边的最大高度。如果左边的较小,左边指针向右推进,然后根据左右两边最小的高度确定当前格子可以存多少水。这里的关键是,将左右两边更小的那个指针向里推进,有点像非递减序列地去填水。

Swift

class Solution {
  func trap(height: [Int]) -> Int {
    if height.count == 0 {
      return 0
    }
    var i = 0
    var j = height.count - 1
    var ret = 0
    var leftHeight = height[0]
    var rightHeight = height[j]
    while i < j {
      let minHeight = min(leftHeight, rightHeight)
      if (leftHeight < rightHeight) {
        i += 1
        let water = max(minHeight - height[i], 0)
        ret += water
        leftHeight = max(leftHeight, height[i])
      } else {
        j -= 1
        let water = max(minHeight - height[j], 0)
        ret += water
        rightHeight = max(rightHeight, height[i])
      }
    }
    
    return ret
  }
}

C++

class Solution {
public:
    /**
     * @param heights: a vector of integers
     * @return: a integer
     */
    int trapRainWater(vector &heights) {
        if (heights.size() == 0) {
            return 0;
        }
        int i = 0;
        int j = heights.size() - 1;
        int leftHeight = heights[i];
        int rightHeight = heights[j];
        int ret = 0;
        while (i < j) {
            int minHeight = min(leftHeight, rightHeight);
            if (leftHeight < rightHeight) {
                i++;
                int water = max(minHeight - heights[i], 0);
                ret += water;
                leftHeight = max(leftHeight, heights[i]);
            } else {
                j--;
                int water = max(minHeight - heights[j], 0);
                ret += water;
                rightHeight = max(rightHeight, heights[j]);
            }
        }
        return ret;
    }
};

你可能感兴趣的:([LeetCode][DP] Trapping Rain Water)