description:

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.
Note:
https://leetcode.com/problems/trapping-rain-water/.
Example:

Example:

Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6

answer:

class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> st;
        int n = height.size();
        int i = 0, res = 0;
        while(i < n) {
            if (st.empty() || height[i] <= height[st.top()]) {
                st.push(i++);
            }
            else {
                int t = st.top();
                st.pop();
                if (st.empty()) {
                    continue;
                }
                res += (min(height[st.top()], height[i]) - height[t]) * (i - st.top() - 1);
            }
        }
        return res;
    }
};
class Solution {
public:
    int trap(vector<int>& height) {
        int res = 0, n = height.size(), mx = 0;
        vector<int> dp(n, 0);
        for (int i = 0; i < n; ++i) {
            dp[i] = mx; // 找到左边最高的
            mx = max(mx, height[i]);
        }
        mx = 0;
        for (int i = n - 1; i >= 0; --i) {
            dp[i] = min(mx, dp[i]); //找到右边最高的之后取左右最高中的最小值
            mx = max(height[i], mx);
            if (dp[i] > height[i]) res += (dp[i] - height[i]); // 如果左右最高中的最小值比这一列的高度高,那么这一列就是可以蓄水的
        }
        return res;
    }
};

relative point get√:

hint :

  • 第一种用堆栈去做的思路大致如下:堆栈里存入的是坐标,如果现在加入的这个数和前面那个数比小,那就一直加入,如果大,那就证明最起码能和它前面那个数形成一个水坑,但是考虑到不能重复计算水面积,所以只是覆盖他们这一层,就是这个水坑的计算是横着一层一层(一行一行)的填满的,自己拿草纸走一遍例子就行了....瞬间明白了...
  • 第二种方法恰恰和上面那种相反,它是不管别的,就看当前这一列能不能存水,也就是说是一列一列来的,比方说第二个0的位置,第一遍遍历的时候发现左边最高是1,第二遍遍历的时候发现右边最高的是3,那么不管两边是个什么情况,就在这一列都是可以蓄水为1的。