//给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 
//
// 
//
// 示例 1: 
//
// 
//
// 
//输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
//输出:6
//解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 
// 
//
// 示例 2: 
//
// 
//输入:height = [4,2,0,3,2,5]
//输出:9
// 
//
// 
//
// 提示: 
//
// 
// n == height.length 
// 0 <= n <= 3 * 104 
// 0 <= height[i] <= 105 
// 
// Related Topics 栈 数组 双指针 动态规划 
// 👍 2406 👎 0

/*
* 42 接雨水
* 2021-06-12 14:43:45
* @author oxygenbytes
*/ 
#include "leetcode.h" 
//leetcode submit region begin(Prohibit modification and deletion)
// [ref]:https://www.acwing.com/solution/content/121/
class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size(); 
        int ans = 0;
        
        stack<int> stk;
        for(int i = 0;i < n;i++){
            // 单减栈
            while(!stk.empty() && height[stk.top()] <= height[i]){
                int top = stk.top();
                stk.pop();
                if(stk.empty()) break;
                ans += (i - stk.top() - 1) 
                       * (min(height[stk.top()], height[i]) - height[top]);
            }
            stk.push(i);
        }
        return ans;
    }
};
//leetcode submit region end(Prohibit modification and deletion)