【题目】
题目链接
Given n non-negative integers representing the histogram’s bar height where the width of each bar is 1, 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 = 10 unit.
For example,
Given heights = [2,1,5,6,2,3],
return 10.
【分析】
最优runtime:
刚看到这道题的时候知道可以用动态规划的写法,但是由于能力有限,所以到最后还是没有写出一个O(n)的写法,只能求助与网上其他博主,才发现思路是:等到heights[i]<=heights[i-1]的时候就计算,求max_height
还有就是可以巧妙地在vector heights后面补一个数0,方面循环
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0);
int size = heights.size();
stack<int> s;
int max_area = 0 ;
for( int i = 0 ; i < size ; i ++ ){
while( !s.empty() && heights[s.top()] > heights[i] ){
int top = s.top();
s.pop();
max_area = max( max_area , heights[top] * ( i - ( s.empty() ? -1 : s.top() ) - 1 ) );
}
s.push(i);
}
return max_area;
}
};
当然我们的stacks的pop操作可以借用i–来改写,避免总是来回pop操作,类似这样:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0);
int size = heights.size();
stack<int> s;
int max_area = 0 ;
for( int i = 0 ; i < size ; i ++ ){
if( s.empty() || heights[s.top()] <= heights[i] ) s.push(i);
else{
int top = s.top();
s.pop();
max_area = max( max_area , heights[top] * ( s.empty() ? i : i - 1 - s.top() ) );
i --;
}
}
return max_area;
}
};
这个时候用的是if-else结构而不是while结构,因为i–,后在for循环中还会i++所以跟上面一种解法的思路是一样的
但是上面两种解法的效率一般一直是在22ms到26ms之间,在leetcode上的runtime只处于50%的程度,这是因为我们总是需要push的操作,每次都需要初始一个空间来push
所以我们可以利用vector或者数组结构,用i++,i–来操作,提高效率
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0);
int cur = 0, max_area = 0, top = 0;
int * stack = new int[heights.size()];
//vector<int> stack( heights.size() , 0 );
stack[top] = -1;
for(int i = 0; i < heights.size(); ++i){
while(top>0 && heights[stack[top]] >= heights[i]){
cur = (i-stack[top-1]-1)*heights[stack[top]];
top--;
max_area = max(cur, max_area);
}
stack[++top] = i;
}
return max_area;
}
};
效率如图: