*42. 接雨水
单调栈存储柱子下标。栈顶到栈底单调递增。
- 当新访问的元素大于栈顶指向元素时,取栈顶指向元素作为中间柱子,栈顶弹出,下一个栈顶指向元素做左侧柱子,当前访问元素做右侧柱子,计算三个柱子中间所接雨水量。重复迭代上述操作直至栈顶元素大于当前元素。最后将当前元素下标放入栈中
- 当新访问元素等于栈顶指向元素时,栈顶弹出将当前元素存入。因为当有两个相同柱子做左边界时,需要取相同柱子里的右侧作为左边界。
- 当新访问元素小于栈顶指向元素时,将当前元素存入栈中。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
// c++
class Solution {
public:
int trap(vector<int>& height) {
int result=0;
stack<int> st;
st.push(0);
for(int i=1; i<height.size(); i++){
if(height[i] == height[st.top()]){
st.pop();
st.push(i);
}else if(height[i] < height[st.top()]){
st.push(i);
}else{
while(!st.empty() && height[i] >= height[st.top()]){
int mid = st.top();
st.pop();
if(!st.empty()){
int left = st.top();
int h = min(height[left], height[i]) - height[mid];
result += h * (i-left-1);
}
}
st.push(i);
}
}
return result;
}
};
*84. 柱状图中最大的矩形
单调栈存储柱子下标。栈顶到栈底单调递减。
在原数组首位各插入一个0.
- 当访问元素大于栈顶指向元素时,直接放入栈中。
- 当访问元素与栈顶指向元素相等时,弹出栈顶,将当前元素放入栈中。
- 当访问元素小于栈顶指向元素时,取栈顶指向元素为中间柱子,弹出栈顶,下一个栈顶指向元素为左边柱子,当前访问元素为右边柱子,计算面积。重复上述过程直至访问元素大于等于栈顶指向元素。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
// c++
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
stack<int> st;
int result = heights[0];
st.push(0);
heights.insert(heights.begin(), 0);
heights.push_back(0);
for(int i=1; i<heights.size(); i++){
if(heights[i] > heights[st.top()]){
st.push(i);
}else if(heights[i] == heights[st.top()]){
st.pop();
st.push(i);
}else {
while(!st.empty() && heights[i] < heights[st.top()]){
int mid = st.top();
st.pop();
if(!st.empty()){
int left = st.top();
int w = heights[mid];
int h = i - left - 1;
result = max(result, w*h);
}
}
st.push(i);
}
}
return result;
}
};