单调栈
42. 接雨水(单调栈解法)
题目描述
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
思路
按行计算雨水大小,需要凹槽,包括最低元素和左右两侧高的元素。
1.保证栈内由栈顶向栈底单增,这样在新元素入栈时,若新元素大于栈顶元素,则找到右侧封口元素;
2.栈内存放位置下标即可,栈顶元素记为mid,出栈;
3.凹槽的高度,左右两侧封口的较小值减去凹槽底部高度,
凹槽的宽度:右侧元素下标减去左侧元素下标再减一。
代码
class Solution {
public:
int trap(vector<int>& height) {
stack<int> st;
int res = 0;
if (height.size() == 0) return res;
st.push(0);
for (int i = 1; i < height.size(); i++)
{
if (height[i] < height[st.top()])
{
st.push(i);
}
else if (height[i] == height[st.top()])
{
st.pop();
st.push(i);
}
else{
while (!st.empty() && height[i] > height[st.top()])
{
int mid = st.top();
st.pop();
if (!st.empty()){
int h = min(height[st.top()], height[i]) - height[mid];
int w = i - st.top() - 1;
res += h * w;
}
}
st.push(i);
}
}
return res;
}
};
84. 柱状图中最大的矩形
题目描述
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
思路
对于位置i,它参与的最大矩形,由其高度,与左右两侧第一个低于他的凸处决定。
1.栈顶到栈底是递减的,此时,若新元素是栈顶元素右侧的凸,则其值小于栈顶元素,形成凸出;
2.凸的高度:height[i]
凸的宽度:右侧下标-左侧下标-1;
3.栈初始化将0位置元素加入,对于结尾元素,其后加一个0.
代码
class Solution {
public:
// i处元素的最大矩形:找左右第一个小于他的位置,采用单调递减栈时,其在栈中向栈底相邻的几位左侧第一个小于它的元素,新元素入栈时,如果新元素比他小,则该新元素为右侧小于他的元素,则第i个元素的最大矩形面积为height[i] * (right_i - left_i - 1)
int largestRectangleArea(vector<int>& heights) {
stack<int> st;
int res = 0;
if (heights.size() == 0) return res;
heights.insert(heights.begin(), 0); // 数组头部加入元素0
heights.push_back(0); // 数组尾部加入元素0
st.push(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 h = heights[mid];
int w = i - st.top() - 1;
res = max(res, w * h);
}
}
st.push(i);
}
}
return res;
}
};