1. 程式人生 > >leetcode題解分析_84. Largest Rectangle in Histogram

leetcode題解分析_84. Largest Rectangle in Histogram

【題目】

題目連結
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;
    }
};

效率如圖:
這裡寫圖片描述