【陪伴式刷题】Day 53|单调栈|84.柱状图中最大的矩形(Largest Rectangle in Histogram)

34 阅读2分钟

刷题顺序以及题解参考卡哥的代码随想录

题目描述

英文版描述

Given an array of integers heights representing the histogram's bar height where the width of each bar is 1, return the area of the largest rectangle in the histogram.

Example 1:

Input: heights = [2,1,5,6,2,3] Output: 10 Explanation: The above is a histogram where width of each bar is 1. The largest rectangle is shown in the red area, which has an area = 10 units.

Example 2:

Input: heights = [2,4] Output: 4

Constraints:

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

英文版地址

leetcode.com/problems/la…

中文版描述

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

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:

输入: heights = [2,1,5,6,2,3] 输出: 10 解释: 最大的矩形为图中红色区域,面积为 10

示例 2:

输入: heights = [2,4] 输出: 4

提示:

提示:

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

中文版地址

leetcode.cn/problems/la…

解题方法

初版

class Solution {
    int largestRectangleArea(int[] heights) {
        Stack<Integer> st = new Stack<Integer>();
        
        // 数组扩容,在头和尾各加入一个元素
        int [] newHeights = new int[heights.length + 2];
        newHeights[0] = 0;
        newHeights[newHeights.length - 1] = 0;
        for (int index = 0; index < heights.length; index++){
            newHeights[index + 1] = heights[index];
        }

        heights = newHeights;
        
        st.push(0);
        int result = 0;
        // 第一个元素已经入栈,从下标1开始
        for (int i = 1; i < heights.length; i++) {
            // 注意heights[i] 是和heights[st.top()] 比较 ,st.top()是下标
            if (heights[i] > heights[st.peek()]) {
                st.push(i);
            } else if (heights[i] == heights[st.peek()]) {
                st.pop(); // 这个可以加,可以不加,效果一样,思路不同
                st.push(i);
            } else {
                while (heights[i] < heights[st.peek()]) { // 注意是while
                    int mid = st.peek();
                    st.pop();
                    int left = st.peek();
                    int right = i;
                    int w = right - left - 1;
                    int h = heights[mid];
                    result = Math.max(result, w * h);
                }
                st.push(i);
            }
        }
        return result;
    }
}

复杂度分析

  • 时间复杂度: O(n),其中 n 是数组的长度
  • 空间复杂度: O(n),其中 n 是数组的长度

精简版

class Solution {public int largestRectangleArea(int[] heights) {int[] newHeight = new int[heights.length + 2];System.arraycopy(heights, 0, newHeight, 1, heights.length);
        newHeight[heights.length+1] = 0;
        newHeight[0] = 0;Stack<Integer> stack = new Stack<>();
        stack.push(0);int res = 0;for (int i = 1; i < newHeight.length; i++) {while (newHeight[i] < newHeight[stack.peek()]) {int mid = stack.pop();int w = i - stack.peek() - 1;int h = newHeight[mid];
                res = Math.max(res, w * h);}
            stack.push(i);}return res;}}