42. 接雨水
利用单调栈先找到左侧第一个大于当前高度的,再用栈的单调特性,弹出的下一个一定大于当前的
就找到了左右的支柱,左右最短的减去当前块高度为h,下标差为w,相乘即为当前块能盛水的面积
cpp
int trap(vector<int>& height) {
if(height.size() == 0){
return 0;
}
int sum = 0;
stack<int> st;
st.push(0);
for(int i = 1; i < height.size(); i++){
if(height[i] > height[st.top()]){
while(!st.empty() && height[i] > height[st.top()]){
int mid = st.top();
st.pop();
if(!st.empty()){
int width = i - st.top() - 1;
int h = min(height[i], height[st.top()]) - height[mid];
sum += width * h;
}
}
}
st.push(i);
}
return sum;
}
84. 柱状图中最大的矩形
单调栈(区别接雨水的栈),找每个柱的「左右第一个更矮柱」,中间部分就是能容纳高度为height[mid]的矩形,宽度就为两侧矮柱横坐标之差
首尾插 0 是关键技巧,避免栈空 / 边界漏算;
核心计算:弹出柱为高,左右边界间距为宽,取面积最大值。
cpp
int largestRectangleArea(vector<int>& heights) {
if(heights.size() == 0){
return 0;
}
stack<int> st;
//首尾插入0
heights.insert(heights.begin(), 0);
heights.push_back(0);
st.push(0);
int res = 0;
for(int i = 1; i < heights.size(); i++){
if(heights[i] < heights[st.top()]){
while(!st.empty() && heights[i] < heights[st.top()]){
int mid = st.top();
st.pop();
if(!st.empty()) {
int h = heights[mid];
int w = i - st.top() - 1;
res = max(res, h*w);
}
}
}
st.push(i);
}
return res;
}