2

84. 柱状图中最大的矩形

image.png

暴力

思路

枚举所有左右边界,然后找到区间内的最小值。

复杂度o(n^3)

耗时过久,故代码略

暴力优化

选取以某个柱子为高,然后左右扩散,保证没有比他小的。

复杂度o(n^2)

代码略

单调栈

这里其实是对暴力优化解法的一种优化,避免了重复的计算。

维护一个单调栈,从小到大
每次遍历一根柱子的时候,如果她比栈顶的大,就入栈,如果他比栈顶的小,就出栈,为什么?因为这个时候比他高的柱子为高的矩形的右边界已经可以确定了!
比如上图中遍历到2的时候,将6,5退栈一直到栈顶元素小于2,例子中也就是栈顶为1的时候。为什么?这个时候5,6的右边界已经确定了,是2这根柱子(不包含这根),左边怎么确定呢?很简单,退栈6的时候他的左边距就是栈顶元素,也就是5.为什么因为栈里的元素都是递增的,所以比他小且最大的元素一定在栈顶。

这里加了一些边界值,方便判断边界情况。

复杂度:o(n)

代码如下:

from typing import List
from collections import deque


class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        queue, n, ans = deque(), len(heights), 0
        queue.append(-1)
        heights.append(-1)

        for index, h in enumerate(heights[:n+1]):
            if h > heights[queue[-1]]:
                queue.append(index)
            else:
                while heights[queue[-1]] > h:
                    t = queue.pop()
                    left_index, right_index = queue[-1], index
                    ans = max((right_index - left_index - 1) * heights[t], ans)
                queue.append(index)
        return ans

北语张益达
6 声望4 粉丝