在代码注释之外再详细说明一下加入相同元素的情况:
举一个例子,
20 和 30 取一个最小值,然后 20 - 20 = 0,所以面积也为0
所以加入或者不加入,都是一样的
class Solution {
public:
int trap(vector<int>& height) {
stack<int> st;
int sum = 0;
st.push(0);
for(int i = 1 ; i < height.size(); i++)
{
// 大体的操作与基础的单调栈类似
/*
这里当 height[i] == height[st.top()]
同样也进入了弹入,因为到最后算的都是一样的
*/
if(height[i] <= height[st.top()])
st.push(i);
else
{
while(!st.empty() && height[i] > height[st.top()])
{
int mid = st.top(); // 存下,因为后面会被pop掉
st.pop();
/*
我觉得最关键的点就是在,找到当前元素左边第一个比它高的元素,和右边第一个比它高的元素
左边第一个高的就是栈口的后面一个元素
(所以这里先将栈口的弹出了,下一个栈口就是左边第一个高的元素,因为栈是单调增的
右边第一个高的就是当前的元素,所以可以根据这三个元素来求得面积
这里求的面积是横向求的。
*/
if(!st.empty())
{
int h = min(height[st.top()], height[i]) - height[mid]; // 这里注意要减去高度
int w = i - st.top() - 1; // 这里求的是宽度,这里减一的话,可以带入实际数字就知道了
sum += h * w; // 面积
}
}
st.push(i);
}
}
return sum;
}
};