【LeetCode】084. 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.

【LeetCode】084. Largest Rectangle in Histogram

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

【LeetCode】084. Largest Rectangle in Histogram

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.

题解:

Solution  1 

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        if(heights.size() < 1)
            return 0;
        return maxArea(heights, 0, heights.size() - 1);
    }
private:
    int combineArea(vector<int> &heights, int l, int m, int r){
        int i = m, j = m;
        int area = 0, h = min(heights[i], heights[j]);
        while(i >= l && j <= r){
            h = min(h, min(heights[i], heights[j]));
            area = max(area, h * (j - i + 1));
            if(i == l)
                ++j;
            else if(j == r)
                --i;
            else {
                if(heights[i - 1] > heights[j + 1])
                    --i;
                else
                    ++j;
            }
        }
        
        return area;
    }
                       
    int maxArea(vector<int> &heights, int l, int r){
        if(l >= r)
            return heights[l];
        int m = l + (r - l) / 2;
        int area = maxArea(heights, l, m - 1);
        area = max(area, maxArea(heights, m + 1, r));
        area = max(area, combineArea(heights, l, m, r));
        return area;
    }
};

Solution  2 摘自geeks ,用到了单调栈的思想

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int res = 0, area_top = 0;
        stack<int> s;
        int n = heights.size();
        int i = 0;
        for(i = 0; i < n;){
            if(s.empty() || heights[s.top()] < heights[i]){
                s.push(i++);
            } else {
                int cur = s.top();s.pop();
                area_top = heights[cur] * (s.empty() ? i : i - s.top() - 1); 
                res = max(res, area_top);
            }
        }
        while(!s.empty()){
            int cur = s.top();s.pop();
            area_top = heights[cur] * (s.empty() ? i : i - s.top() - 1);
            res = max(res, area_top);
        }
        return res;
    }
};

Solution  3 优化版

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int res = 0;
        stack<int> s;
        int n = heights.size();
        heights.push_back(0);
        for(int i = 0; i <= n;){
            if(s.empty() || heights[s.top()] < heights[i]){
                s.push(i++);
            } else {
                int cur = s.top();s.pop();
                int area_top = heights[cur] * (s.empty() ? i : i - s.top() - 1); 
                res = max(res, area_top);
            }
        }
        return res;
    }
};

Solutin 4 实际上有些类似,不过把栈的空间复杂度转化为求面积时的时间复杂度,实际上花费时间要多,不推荐此做法。

class Solution {
public:
    int largestRectangleArea(vector<int> &heights) {
        int res = 0, n = heights.size() - 1;
        for (int i = 0; i < heights.size(); ++i) {
            if (i < n - 1 && heights[i] <= heights[i + 1]) {
                continue;
            }
            int h = heights[i];
            for (int j = i; j >= 0; --j) {
                h = min(h, heights[j]);
                int area = h * (i - j + 1);
                res = max(res, area);
            }
        }
        return res;
    }
};

Solution 4 摘自geeks  基于线段树