[leetcode] 42. Trapping Rain Water

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.
这里写图片描述

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!

题意:
      给出非负整数,表示柱状图的高度,在这里每个柱的宽度为1,计算可以收集多少雨水。
      如图的例子可以看出怎么存储雨水的。

方法一:
    思路:
        先从左侧开始向右侧开始遍历数组,用一个队列preVec来存储比队列头小的元素值,当遍历出现比队列头大的元素时,此时队列头比队列中其余元素大的值就是所收集的雨水,直接相加,然后更新队列头元素,继续遍历,直到遍历数组结束,此时如果preVec中还有元素表明preVec队列头比后面元素都大,但是不确定preVec中的元素能收集多少雨水,所以重新按照上面的思路从队列preVec尾到头遍历,求出所存储的雨水。代码如下(此代码效率不高):

class Solution {
public:
    int trap(vector<int>& height) {
        if(height.size()<=2)
            return 0;
        int sum = 0;
        deque<int> preVec;
        for(int i = 0;i < height.size();i++)
        {
            if(preVec.empty() || height[i]<preVec[0])
            {
                preVec.push_back(height[i]);
            }
            else
            {
                while(!preVec.empty())
                {
                    sum += preVec[0] - preVec.back();
                    preVec.pop_back();
                }
                preVec.push_back(height[i]);
            }
        }

        deque<int> lastVec;
        for(int i = preVec.size()-1;i>=0;i--){
            if(lastVec.empty() || preVec[i]<lastVec[0])
            {
                lastVec.push_back(preVec[i]);
            }
            else
            {
                while(!lastVec.empty())
                {
                    sum += lastVec[0] - lastVec.back();
                    lastVec.pop_back();
                }
                lastVec.push_back(preVec[i]);
            }

        }

        return sum;
    }
};

方法二:
    思路:
        采用left和right两个指针,维护装水两边的位置,这道题最主要的就是两边往中间遍历。
        当left处高度低时,说明left右侧装的水肯定和left处一样高,此时逐步右移left,同是记录当前第二高点secHeight,加上left处与右移后位置高度差(因为这里都能装水啊)即然利用这个第二高点secHeight减去当前历经的柱子,直到再遇到同样高或者更高的位置。然后进行下一轮判断。
        同样,当right处高度低时,说明right左侧的水肯定和right处一样高,此时逐步左移right,同是记录当前第二高点secHeight,加上right处与左移后位置高度差,即然利用这个第二高点secHeight减去当前历经的柱子,直到再遇到同样高或者更高的位置。
        最后直到left和right相遇,结束。代码如下:

class Solution {
public:
    int trap(vector<int>& height) {
        if(height.size()<=2)
            return 0;
        int area=0,secHight=0,left = 0,right = height.size()-1;
        while(left<right)
        {
            if(height[left]<height[right])//控制从左向右计算雨水量
            {
                secHight = max(height[left],secHight);
                area +=(secHight - height[left]);
                left++;
            }
            else//控制从右向左计算雨水量
            {
                secHight = max(height[right],secHight);
                area +=(secHight - height[right]);
                right--;
            }
        }

        return area;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值