zoukankan      html  css  js  c++  java
  • 42. Trapping Rain Water (Array,stack; DP)

    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!

    思路:动态规划。第一次存储从开始到i最高的位置,求最高位置a之前的存水量=a与a之前最高位置b之间的水量+b与b之前最高位置c之间的水量...

    第二次存储从末尾到i最高的位置,求最高位置a之后的存水量=a与a之前最高位置m之间的水量+m与m之前最高位置n之间的水量...

    class Solution {
    public:
        int trap(vector<int>& height) {
            int size = height.size();
            if(size==0) return 0;
            
            vector<int> dp(size,0); //save the highest position until now
            int ret = 0;
            int left,right;
            
            //first traverse from left to right
            for(int i = 1; i < size; i++){
                //state transfer
                if(height[i] > height[dp[i-1]]) dp[i]=i;
                else dp[i] = dp[i-1];
            }
            
            //calculate the water to the left of the highest position
            left = dp[size-1];
            while(left>0){
                right=left;
                left=dp[right-1];
                for(int i = left+1; i < right; i++){
                    ret += (height[left]-height[i]);
                }
            }
      
            //second traverse from right to highest pos
            int highestPos=dp[size-1];
            dp[size-1]=size-1;
            for(int i = size-2; i >= highestPos; i--){
                //state transfer
                if(height[i] > height[dp[i+1]]) dp[i]=i;
                else dp[i] = dp[i+1];
            }
       
            //calculate the water to the right of the highest position
            right=highestPos;
            while(right<size-1){
                left=right;
                right=dp[left+1];
                for(int i = left+1; i < right; i++){
                    ret += (height[right]-height[i]);
                }
            }
            
            return ret;
        }
    };

     改进:用stack代替vector作为状态存储。stack的栈顶是到目前为止最大元素的下标,因为最高位置是关键,找到最高位置,可以往左,往右计算水位。

    stack的实现类似用两个stack实现能够返回最大元素的stack。

    class Solution {
    public:
        int trap(vector<int>& height) {
            int size = height.size();
            if(size==0) return 0;
            
            stack<int> s;
            s.push(0);
            int i, ret = 0, highestPos;
            
            
            //First traverse from left to right
            for(int i = 0; i < size; i++){
                if(height[i]<=height[s.top()]) continue;
                
                s.push(i);
            }
            
            i=s.top();
            highestPos = i;
            while(1){
                if(i==s.top()){
                    s.pop();
                    if(s.empty()) break;
                }
                else{
                    ret+=(height[s.top()]-height[i]);
                }
                i--;
            }
            
            //then traverse from right to left
            s.push(size-1);
            for(int i = size-2; i >= highestPos; i--){
                if(height[i]<=height[s.top()]) continue;
                
                s.push(i);
            }
            
            i=highestPos;
            while(1){
                if(i==s.top()){
                    s.pop();
                    if(s.empty()) break;
                }
                else{
                    ret+=(height[s.top()]-height[i]);
                }
                i++;
            }
            return ret;
        }
    };
  • 相关阅读:
    Java GC系列(2):Java垃圾回收是如何工作的?
    BZOJ 2878 【NOI2012】 迷失游乐园
    BZOJ 2876 【NOI2012】 骑行川藏
    UOJ #126 【NOI2013】 快餐店
    BZOJ 3122 【SDOI2013】 随机数生成器
    BZOJ 1833 【ZJOI2010】 数字计数
    BZOJ 1269 【AHOI2006】 文本编辑器
    BZOJ 3930 【CQOI2015】 选数
    BZOJ 4569 【SCOI2016】 萌萌哒
    BZOJ 2756 【SCOI2012】 奇怪的游戏
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/4863574.html
Copyright © 2011-2022 走看看