Leetcode84柱状图中最大的矩形
题目链接:84柱状图中最大的矩形
1、双指针法:
寻找左边第一个小于该元素的下标,寻找右边第一个小于该元素的下标,
w = minfirstright[i] - minfirstleft[i] - 1;
h = heights[i];
result = max(result, heights[i]);
双指针法寻找第一个小于该元素的下标:
寻找左边时从左到右遍历,t = i - 1,如果heights[t] >= heights[i],说明大了,令 t = minfirstleft[t],继续寻找比当前值小的下标,每个下标都记录着第一个小于自己的下标,如果没有则返回-1。
寻找右边时从右到左遍历,t = i + 1。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
vector<int> minfirstleft(heights.size());
vector<int> minfirstright(heights.size());
int size = heights.size();
minfirstleft[0] = -1;
for (int i = 1; i < size; i++)
{
int t = i - 1;
while(t >= 0 && heights[t] >= heights[i])
{
t = minfirstleft[t];
}
minfirstleft[i] = t;
}
minfirstright[size - 1] = size;
for (int j = size - 2; j >= 0; j--)
{
int t = j + 1;
while(t < size && heights[t] >= heights[j])
{
t = minfirstright[t];
}
minfirstright[j] = t;
}
int result = 0;
for (int i = 0; i < size; i++)
{
int w = minfirstright[i] - minfirstleft[i] - 1;
int h = heights[i];
result = max(result, h * w);
}
return result;
}
};
2、单调栈法
如果当前元素大于栈顶元素,把当前元素下标入栈;
如果当前元素等于栈顶元素,去掉栈顶元素,把当前元素下标入栈;
如果当前元素小于栈顶元素,当栈不为空且当前元素一直小于栈顶元素时,用mid记录栈顶元素然后弹出,w = i - st.top() - 1, h = heights[mid];
注意,如果数组是[2,4,6,8],则会一直入栈,没有计算面积的操作,所以要在数组后面加一个0。
如果数组是[8,6,4,2],一直弹出栈顶元素,但栈为空时也没有计算面积的操作,所以要在数组前面加一个0。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.insert(heights.begin(), 0);
heights.push_back(0);
int result = 0;
stack<int> st;
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();
int h = heights[mid];
int w = i - st.top() - 1;
result = max(result, h * w);
}
st.push(i);
}
}
return result;
}
};