leetcode
leetcode 51 ~ 100
柱状图中最大的矩形

柱状图中最大的矩形

难度:

标签:

题目描述

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

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

 

示例 1:

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

示例 2:

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

 

提示:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

代码结果

运行时间: 104 ms, 内存: 0.0 MB


/*
 * Problem Statement:
 * Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of the largest rectangle in the histogram.
 * 
 * Approach (Java Stream):
 * Java Stream API is not the most suitable tool for this specific problem because of its imperative nature requiring stack and iterative steps. However, we can illustrate a basic flow using stream for input handling or similar simple operations. This code doesn't leverage Java Stream for the core logic.
 */
 
import java.util.Arrays;
import java.util.Stack;
 
public class Solution {
    public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) return 0;
        Stack<Integer> stack = new Stack<>();
        int maxArea = 0;
        int n = heights.length;
 
        for (int i = 0; i <= n; i++) {
            int h = (i == n) ? 0 : heights[i];
            while (!stack.isEmpty() && h < heights[stack.peek()]) {
                int height = heights[stack.pop()];
                int width = stack.isEmpty() ? i : i - stack.peek() - 1;
                maxArea = Math.max(maxArea, height * width);
            }
            stack.push(i);
        }
        return maxArea;
    }
}
 

解释

方法:

本题解使用单调栈的方法来解决柱状图中最大矩形面积的问题。具体思路如下: 1. 维护一个单调递增的栈,栈中存储柱子的索引。 2. 遍历柱子高度数组,对于每个柱子: - 如果当前柱子的高度小于栈顶索引对应的柱子高度,则持续出栈,直到栈为空或者栈顶柱子高度小于当前柱子高度。 - 对于每个出栈的柱子,计算以其高度为矩形高度的最大矩形面积,更新最大面积。 - 将当前柱子的索引入栈。 3. 返回最大矩形面积。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在算法中添加一个高度为0的柱子到数组末尾的目的是什么?
在数组末尾添加一个高度为0的柱子的主要目的是确保所有在栈中的柱子都能被完全处理。这样做可以触发栈中所有剩余柱子的出栈操作,因为0比任何正高度都小,这保证了在遍历结束时栈为空,使得算法能够计算出所有可能的矩形面积并找到最大值。
🦆
当栈中所有元素被弹出后,如何确定新的栈顶元素的索引,并且这对最大面积的计算有什么影响?
当栈中所有元素被弹出后,新的栈顶元素的索引会是下一个在栈中的元素索引。如果栈变为空,则意味着当前弹出的柱子左侧没有更低的柱子,因此左侧边界被设为-1。这个索引对最大面积的计算至关重要,因为它帮助确定了柱子的宽度。如果栈为空,说明当前柱子左侧没有更小的柱子,其宽度可以扩展到整个数组的起始位置。
🦆
为什么选用单调递增栈而不是单调递减栈?在这种情况下单调递减栈是否会工作?
单调递增栈被选用是因为它可以在遇到一个较小的元素时,方便地处理所有在栈中并且高度高于当前元素的柱子。这样可以立即计算出以这些柱子为高度的最大矩形面积。使用单调递减栈也可以解决问题,但处理逻辑略有不同,主要是在处理矩形宽度时需要更多的考虑,例如延伸到更远的右边界。因此,单调递增栈在逻辑上更直接和简洁。
🦆
在计算矩形宽度时,使用的公式是 'width = index - left_index - 1',请解释为什么要减1?
公式中的'减1'是因为需要排除当前处理的柱子本身。'index'是当前柱子的索引,而'left_index'是上一个在栈中且高度小于当前柱子的索引。因此,实际的可用宽度是从'left_index + 1'到'index - 1'。例如,若'left_index'为2且'index'为5,那么宽度应为5 - 2 - 1 = 2,即索引为3和4的两根柱子。

相关问题

最大矩形

给定一个仅包含 01 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

 

示例 1:

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。

示例 2:

输入:matrix = [["0"]]
输出:0

示例 3:

输入:matrix = [["1"]]
输出:1

 

提示:

  • rows == matrix.length
  • cols == matrix[0].length
  • 1 <= row, cols <= 200
  • matrix[i][j]'0''1'