89 柱状图中最大的矩形

柱状图中最大的矩形

    • 类似接雨水(反过来,相当于找接雨水最少的一段)
    • 题解1 暴力搜索(超时) O ( N 2 ) O(N^2) O(N2)
      • 另一种
    • 题解2 单调栈【重点学习】
      • 常数优化

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。
89 柱状图中最大的矩形_第1张图片
提示:

  • 1 <= heights.length <= 1 0 5 10^5 105
  • 0 <= heights[i] <= 1 0 4 10^4 104

类似接雨水(反过来,相当于找接雨水最少的一段)

题解1 暴力搜索(超时) O ( N 2 ) O(N^2) O(N2)

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int s = heights.size();
        int maxs = 0;
        for(int l = 0; l < s; l++){
            int minL = INT_MAX;
            for(int r = l; r < s; r++){
                minL = min(minL, heights[r]);
                maxs = max(maxs, minL*(r-l+1));
            }
        }
        return maxs;
    }
};

另一种

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int s = heights.size();
        int maxs = 0;
        for(int i = 0; i < s; i++){
            int l = i;
            int r = i;
            int tmph = heights[i];
            while(l >= 1 && heights[l-1] >= tmph)
                --l;
            while(r + 1 < s && heights[r+1] >= tmph)
                ++r;
            maxs = max(maxs, (r-l+1)*tmph);
        }
        return maxs;
    }
};

题解2 单调栈【重点学习】

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int s = heights.size();
        stack<int> stk; // 单调栈,下标对应值保持非严格递增
        vector<int> l(s, -1), r(s, s);
        int maxs = 0;
        // 从左向右
        // 找到离i最近的 < hegihts[i]的左边界
        for(int i = 0; i < s; i++){
            while(stk.size() && heights[stk.top()] >= heights[i])
                stk.pop();
            l[i] = (stk.empty() ? -1 : stk.top());
            stk.push(i);
        }
        stk = stack<int>();
        // 从右向左
        // 找到离i最近的 < hegihts[i]的右边界
        for(int i = s-1; i >= 0; i--){
            while(stk.size() && heights[stk.top()] >= heights[i])
                stk.pop();
            r[i] = (stk.empty() ? s : stk.top());
            stk.push(i);
        }
        for(int i = 0; i < s; i++){
        // 使用单调栈的初衷: 以height[i]为高度的矩形对应的宽 = r[i]-l[i]
            maxs = max(maxs, heights[i]*(r[i]-l[i]-1));
        }
        return maxs;
    }
};

89 柱状图中最大的矩形_第2张图片

常数优化

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int s = heights.size();
        stack<int> stk; // 单调栈,下标对应值保持非严格递增
        vector<int> l(s, -1), r(s, s);
        int maxs = 0;
        // 从左向右
        for(int i = 0; i < s; i++){
            while(stk.size() && heights[stk.top()] >= heights[i]){
                r[stk.top()] = i;
                stk.pop();
            }
                
            l[i] = (stk.empty() ? -1 : stk.top());
            stk.push(i);
        }
        
        for(int i = 0; i < s; i++){
            maxs = max(maxs, heights[i]*(r[i]-l[i]-1));
        }
        return maxs;
    }
};

89 柱状图中最大的矩形_第3张图片

你可能感兴趣的:(栈,HOT100,算法,leetcode,数据结构)