【題目】
題目連結
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();
int size = heights.size();
stack<int> s;
int max_area = ;
for( int i = ; 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() ? - : s.top() ) - ) );
}
s.push(i);
}
return max_area;
}
};
當然我們的stacks的pop操作可以借用i–來改寫,避免總是來回pop操作,類似這樣:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back();
int size = heights.size();
stack<int> s;
int max_area = ;
for( int i = ; 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 - - 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();
int cur = , max_area = , top = ;
int * stack = new int[heights.size()];
//vector<int> stack( heights.size() , 0 );
stack[top] = -;
for(int i = ; i < heights.size(); ++i){
while(top> && heights[stack[top]] >= heights[i]){
cur = (i-stack[top-]-)*heights[stack[top]];
top--;
max_area = max(cur, max_area);
}
stack[++top] = i;
}
return max_area;
}
};
效率如圖: