[LeetCode]84. Largest Rectangle in Histogram
题目描述
思路
开始的想法,对每个点,左右搜索比他小的元素并计数,返回结果乘
但是这种做法会超时
看了答案的栈的做法
如果对于有序数组
1,2,3
那么返回的结果是max(1 * 3, 2 * 2, 3 * 1)
对于无序数组的处理方式,借助栈
以题目中的样例为例
数组–[2, 1, 5, 6, 2, 3]
开始,栈为空
2入栈
此时栈中元素 {2}
对下一个元素1,小于栈顶元素2,入栈的话不满足有序的条件,因此2出栈,同时更新最大结果 res = 2 * 1 = 2
之后对于1,可以延伸到2,为保持有序,将之前出栈的元素2按照当前元素1的大小入栈,并将1入栈
此时栈中元素{1, 1}
对下一个元素5,大于栈顶元素1,入栈
此时栈中元素{1, 1, 5}
对下一个元素6,大于栈顶元素5,入栈
此时栈中元素{1, 1, 5, 6}
对下一个元素2,小于栈顶元素6,入栈后不满足有序条件,因此将栈顶元素6出栈,更新最大结果res = (max, 6 *1) = 6
此时栈中元素{1, 1, 5}
继续使用2和栈顶元素5比较,不可以入栈,因此栈顶元素5出栈,更新最大结果res = max(res, 5 * 2) = 10
此时栈中元素{1,1}
此时2大于栈顶元素1,符合入栈条件,入栈前,将之前出栈的5,6按照当前元素2的大小入栈,之后再将2入栈
此时栈中元素为{1, 1, 2, 2, 2}
对于下一个元素3, 大于栈顶元素2,入栈
对原数组遍历完成
之后处理栈
当栈不为空时
计算栈顶元素 * (count++),若符合更新结果条件,则更新结果。
直到栈为空
得到最终结果
代码
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
class Solution {
public:
int largestReactangleArea(vector<int>& heights) {
/*
int len = heights.size(), res = 0;
for (int i = 0; i < len; ++i) {
int count = 0;
if (i != 0 && heights[i] == heights[i - 1])
continue;
for (int k = i - 1; k >= 0; --k) {
if (heights[k] >= heights[i])
++count;
else
break;
}
for (int k = i; k < len; ++k) {
if (heights[k] >= heights[i])
++count;
else
break;
}
res = res > count * heights[i] ? res : count * heights[i];
}
return res;
*/
int res = 0, count = 0;
stack<int> s;
for (int p : heights) {
if (s.empty() || s.top() <= p) {
s.push(p);
}
else {
while (s.size() > 0 && s.top() > p) {
++count;
res = max(res, count * s.top());
s.pop();
}
while (count) {
s.push(p);
--count;
}
s.push(p);
}
}
while (!s.empty()) {
++count;
res = max(res, count * s.top());
s.pop();
}
return res;
}
};
int main() {
vector<int> nums = { 2,1,5,6,2,3 };
Solution s;
cout << s.largestReactangleArea(nums) << endl;
system("pause");
}