柱状图中最大的矩形算法详解
一、问题描述
给定n
个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为1。要求在该柱状图中,找出能够勾勒出来的矩形的最大面积。
例如:
输入: heights = [2,1,5,6,2,3]
输出: 10
解释: 最大的矩形为图中红色区域,面积为10 。
二、解题思路
- 暴力解法
- 对于每一个柱子,我们尝试以它为高,向左右两边扩展,找到能包含它的最大宽度。
- 具体做法是,对于数组中的每一个元素
heights[i]
,从i
位置向左遍历找到第一个小于heights[i]
的柱子位置left
,从i
位置向右遍历找到第一个小于heights[i]
的柱子位置right
。那么以heights[i]
为高的矩形宽度就是right - left - 1
,面积就是heights[i] * (right - left - 1)
。通过遍历整个数组,记录下最大的面积。 - 时间复杂度:这种方法需要两层循环,外层循环遍历每个柱子,内层循环分别向左和向右寻找边界,所以时间复杂度为O(n2)O(n^2)O(n2),其中
n
是柱子的数量。
- 单调栈解法
- 单调栈是一种特殊的数据结构,它维护栈内元素的单调性(单调递增或单调递减)。在本题中,我们使用单调递增栈。
- 遍历柱子高度数组,当遇到的高度大于栈顶元素对应的高度时,将当前索引压入栈。如果遇到的高度小于栈顶元素对应的高度,说明栈顶元素对应的柱子的右边边界已经找到(就是当前位置),此时弹出栈顶元素。设弹出的栈顶元素索引为
top
,那么它对应的矩形宽度就是当前位置i
(右边边界)减去栈顶元素(新的栈顶)的下一个位置(左边边界),高度就是弹出的栈顶元素对应的高度heights[top]
。通过不断维护和计算,我们可以得到最大的矩形面积。 - 时间复杂度:由于每个元素最多进栈和出栈一次,所以时间复杂度为