接雨水问题,用单调栈解决

单调栈解决,所以我们首先定义一个整形栈。我们首先将0下标入栈。也就是接雨水的左边界。

        if (height.size() <= 2) return 0; // 可以不加
        stack<int> st; // 存着下标,计算的时候用下标对应的柱子高度
        st.push(0);
        int sum = 0;

然后我们开始循环,直到节水区域的右边界。入栈的规则是:保证在入当前元素前,栈中没有比当前元素小的元素。所以就有三种情况,,一种是小于当前元素,一种是等于当前元素,一种是大于当前元素。所以我们有三个条件判断

class Solution {
public:
    int trap(vector<int>& height) {
        if (height.size() <= 2) return 0; // 可以不加
        stack<int> st; // 存着下标,计算的时候用下标对应的柱子高度
        st.push(0);
        int sum = 0;
        for (int i = 1; i < height.size(); i++) {
            if (height[i] < height[st.top()]) {     // 情况一
                st.push(i);
            } if (height[i] == height[st.top()]) {  // 情况二
                st.pop(); // 其实这一句可以不加,效果是一样的,但处理相同的情况的思路却变了。
                st.push(i);
            } else {                                // 情况三
                while (!st.empty() && height[i] > height[st.top()]) { // 注意这里是while
                    int mid = st.top();
                    st.pop();
                    if (!st.empty()) {//在情况二中如果没有st.pop()的话,如果遇到相同且相邻的高度的话,我们需要多次进入此循环。
                        int h = min(height[st.top()], height[i]) - height[mid];//
                        int w = i - st.top() - 1; // 注意减一,只求中间宽度
                        sum += h * w;
                    }
                }
                st.push(i);
            }
        }
        return sum;
    }
};

当然,上面的三种情况可以化简

class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> st;
        st.push(0);
        int sum = 0;
        for (int i = 1; i < height.size(); i++) {
            while (!st.empty() && height[i] > height[st.top()]) {
                int mid = st.top();
                st.pop();
                if (!st.empty())//这里的条件为了避免多次运算的话可以这样写(如果有更多的是相同的高度的话)
                //if (!st.empty()&&height[mid]!=height[st.top()]),也就是重现上述的情况二
                {
                    int h = min(height[st.top()], height[i]) - height[mid];
                    int w = i - st.top() - 1;
                    sum += h * w;
                }
            }
            st.push(i);
        }
        return sum;
    }
};

你可能感兴趣的:(c++,开发语言,动态规划)