42. Trapping Rain Water

题目

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
.

42. Trapping Rain Water_第1张图片

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. Thanks Marcos for contributing this image!

分析

思路是首先求得每个位置的水面高度,再由其求得水的体积。
而求水面高度,则可分为两种情况:

  • 当前位置后有大于等于当前高度的位置,则自该位置起,将水面高度赋为当前高度
  • 当前位置后没有大于等于当前高度的位置了,则自该位置之后,将水面高度赋为其之后的最高高度。

由于这两种情况都需要用到其后的最大高度,所以可以使用一个数组保存该值。另外别忘了每个位置的水面高度不能低于该位置的高度。

实现

class Solution {
public:
    int trap(vector& height) {
        if(height.size()<=1) return 0;
        int n = height.size();
        int maxheight[n] = {0};
        int maxpos[n] = {0};
        int water[n] = {0};
        maxheight[n-1] = height[n-1];
        maxpos[n-1] = n-1;
        for(int i=n-2; i>=0; i--){
            if(height[i] >= maxheight[i+1]){
                maxheight[i] = height[i];
                maxpos[i] = i;
            }
            else{
                maxheight[i] = maxheight[i+1];
                maxpos[i] =maxpos[i+1];
            }
        }
        int i=0;
        while(i=maxheight[i+1]){
                water[i] = height[i];
                for(int j=i+1; j<=maxpos[i+1]; j++){
                    water[j] = maxheight[i+1];
                }
                i = maxpos[i+1];
            }
            else{
                int tmp = height[i];
                while(i

思考

看了题解发现有更简单的思路:

  • 扫描一遍, 找到最高的柱子,该柱子将数组分成左右两组
  • 对于两组分别处理

参考代码

class Solution{
  public:
    int trap(const vector &A){
        const int n = A.size();
        int max = 0; //最高的柱子,将数组分成两半
        for (int i = 0; i < n; i++)
            if (A[i] > A[max])
                max = i;
        int water = 0;
        for (int i = 0, peak = 0; i < max; i++)
            if (A[i] > peak)
                peak = A[i];
            else
                water += peak - A[i];
        for (int i = n - 1, top = 0; i > max; i--)
            if (A[i] > top)
                top = A[i];
            else
                water += top - A[i];
        return water;
    }
};

你可能感兴趣的:(42. Trapping Rain Water)