LeetCode OJ:Trapping Rain Water

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!

算法思想:

有点类似于最大子矩阵问题: 

[置顶] 动态规划4:最大子段和问题到最大子矩阵问题(四):最大子矩阵面积问题

class Solution {
public:
    int trap(int A[], int n) {
        if(!n)return 0;
        vector<int> L(n);
        vector<int> R(n,n);
        int result=0;
        int maxH=0;
        for(int i=0;i<n;i++){
            L[i]=maxH;
            maxH=max(L[i],A[i]);
        }
        R[n-1]=0;
        maxH=A[n-1];
        for(int i=n-2;i>0;i--){
            R[i]=maxH;
            maxH=max(R[i],A[i]);
            int height=min(L[i],R[i]);
            if(height>A[i]){
                result+=height-A[i];
            }
        }
        return result;
    }
};

answer2:

找到最高的柱子max,从左向右扫描到max,然后从右向左扫描到max

时间复杂度O(n),空间复杂度O(1)

class Solution {
public:
    int trap(int A[], int n) {
        
        int result=0;
        int max=0;
        for(int i=0;i<n;i++)if(A[i]>A[max])max=i;
        for(int i=0,peak=0;i<max;++i){
            if(A[i]>peak)peak=A[i];
            else result+=peak-A[i];
        }
        for(int i=n-1,peak=0;i>max;--i){
            if(A[i]>peak)peak=A[i];
            else result+=peak-A[i];
        }
        return result;
    }
};

answer3

辅助栈,栈中始终保持一个递减序列,小于栈顶的元素压入,大于或等于栈顶就把所有小于等于当前值得元素出栈

时间复杂度O(n),空间复杂度O(n)

class Solution {
public:
    int trap(int A[], int n) {
        stack<pair<int,int>> s;
        int water=0;
        
        for(int i=0;i<n;++i){
            int height=0;
            
            while(!s.empty()){
                int bar=s.top().first;
                int pos=s.top().second;
                water+=(min(bar,A[i])-height)*(i-pos-1);
                height=bar;
                
                if(A[i]<bar)break;
                else s.pop();
            }
            s.push(make_pair(A[i],i));
        }
        return water;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值