接雨水

算法一:动态规划法
dp[i]表示当前位置能接多少单位的水
dp[i]的存水量是i最左边和最高高度lmax和最右边的最高的高度lmax中的相对低的一个的高度再减去当前i的高度
所以使用一个lmax数组和rmax数组来预处理i左边的最大高度和右边的最大高度

class Solution {
public:
    int trap(vector<int>& h) {
        int n = h.size();
        vector<int> l(n), r(n);
        l[0] = h[0], r[n - 1] = h[n - 1];
        for(int i = 1; i < n; i ++)
            l[i] = max(l[i - 1], h[i]);
        for(int i = n - 2; i >= 0; i --)
        {
            r[i] = max(r[i + 1], h[i]);
        }
        int res = 0;
        for(int i = 0; i < n; i ++)
        {
            res += min(l[i], r[i]) - h[i];
        }
        return res;
    }
};

算法二:单调栈
维护一个单调递减栈, 当遇到第一个递增的h[i]时, 那么一定是可以蓄水的,栈顶元素h[top]的前一个元素充当左边界,h[i]充当右边界,蓄水量就是左右边界中间的体积减去柱子的高度

class Solution {
public:
    int trap(vector<int>& h) {
       stack<int> sk;
       int n = h.size();
       int i = 0, res = 0;
       while(i < n)
       {
           while(sk.size() && h[i] > h[sk.top()])
           {
                int top = sk.top();
                sk.pop();
                if(sk.empty())break;
                int l = sk.top();
                int width = i - l - 1;//宽度
                int length = min(h[l], h[i]) - h[top];//高度
                res +=  length * width;
           }
           sk.push(i ++);
       }
       return res;
    }
};
上一篇:1. RocketMq 消息重发的次数


下一篇:[转]python 网络篇(网络编程) - 超天大圣 - 博客园