原题网址:https://leetcode.com/problems/largest-rectangle-in-histogram/description/
题目描述:
Given n non-negativeintegers representing the histogram's bar height where the width of each bar is1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2, 1,5, 6, 2, 3],
The largest rectangle is shown in the shaded area, which has area = 10unit.
For example,
Given heights = [2, 1, 5, 6, 2, 3],
return 10.
大致题意:
给出一组数据,分别代表柱状图的高度,求出柱状图中最大矩形的面积。每个单位长度默认为1。
题目解析:
如果直接遍历来的话,时间复杂度较大,因此寻求一种可降低时间复杂度的做法。
采用栈的结构
1、柱状图寻找面积最大区域的最简单的一种情况是高度这组数是递增的,这样的话,从坐标轴从右往左来看,最大的面积就是底边宽度乘以当前最靠左的柱的高度。依次比较。
2、利用栈的结构来构造这种理想化的模型。
(1)维护一个递增的栈,拿一个当前的矩形元素,如果当前的高度比前面的要高,入栈;如果比当前的高度要低,则弹出,继续与此时的栈顶比较。重复步骤直至当前该元素高度高于当前栈顶。
(2)弹出的栈当然也不能完全扔掉不管,因为最终要求解的矩形也可能在这个模块里。但弹出的柱状中最大矩形面积就是最后弹出的那个乘以弹出的个数(因为弹出的话最后弹出的一定是最小的)。
(3)这样就用一个变量每次更新面积最大值即可。但是弹出后也要补回来,补在栈后面的矩形高度与当前拿来比较的(高度最低)的矩形一致(维护递增)。按照当前元素的高度补回来同样个数的等高的矩形元素即可。
(4)这时候再用第(1)步中的方法遍历一下这个理想化模型,边遍历便与第(3)步保存面积的变量的面积值比较,最终得出最优解。
下面是代码:
#include <iostream>
#include <vector>
#include <string>
#include <stack>
using namespace std;
int largestRectangleArea(vector<int> &height)
{
stack<int> curMap;
int ans = -1;
for(int i = 0; i < height.size(); i++)
{
if(curMap.empty() || height[i] >= curMap.top())
{
curMap.push(height[i]);
}
else if(height[i] < curMap.top())
{
int cnt = 0;
while(!curMap.empty() && !(curMap.top() <= height[i]) )
{
cnt++;
ans = max(ans, cnt*curMap.top());
curMap.pop();
}
while(cnt--)
{
curMap.push(height[i]); //把弹出的按最小值弹入
}
curMap.push(height[i]); //比较的这个也弹入
}
}
//计算剩下的
int cnt = 1;
while( !curMap.empty() )
{
ans = max(ans, cnt*curMap.top());
curMap.pop();
cnt++;
}
return ans;
}
int main()
{
while(1)
{
vector<int> height;
int ans;
int t;
while(1)
{
cin >> t;
height.push_back(t);
if(cin.get() == '\n')
{
break;
}
}
ans = largestRectangleArea(height);
cout << ans << endl;
}
return 0;
}