所以对柱子 i
的扩展,往左右两边找,碰到矮的停下来,确定两边边界,边界高度
Hj=hi,这个即是这个 i 自己能做出来的最大矩形。
可以双重循环扫描,但不是重点,这里学习题解大神的栈思路。 #
题解分析:栈保留边界
首先有一层主循环遍历所有柱子,从左到右,当前柱子为 i。
我们目的是要找i的两个边界,因为是从左到右扫描,即我们可以顺手找到
i 的右边界。只要扫描时碰到比 i 矮的就知道这个是右边界了。
但是碰到比 i 高或者相等的柱子 j 怎么办呢?j 不会是 i 的边界
,但我们也要找 j 的边界。因此我们要把未处理的 i 和 j 都留下来。
而继续往后找的时候, i 的右边界x 必然是 j 的右边界或者之外
(hi<=hj) 。 因此对于下一个柱子 x: 4.1
假如我们先判断 x 是不是 i 的边界,假如它是,它也不一定就是 j 的右边界
,我们还得用 x 和 j 比较一次。假如它不是,它也不一定就不是 j
的右边界,还是得 x j 比较一次,所以先判定 i
的边界很鸡肋。 4.2 假如先判断 x 是不是更高的 j
的右边界,假如它不是,那么肯定也不是 i
的边界,假如它是,那么可以继续判定是不是更矮的 i 的右边界。
右边界解决了,我们还需要确定每个柱子 i 的左边界,左边界肯定在左边
, 并且左边界也要比 i 矮,而我们的栈又是高度递增的=
=+显然,我们可以利用出栈过程。 在栈顶确定了右边界,然后出栈的时候: 6.1
下面的那个柱子高度大于【栈顶右边界高度Hr】,那么这个柱子不是左边界,而可以组成这个矩形(因为有右边界后,矩形最低高度是Hr,只要高于Hr,都是)我们继续出栈寻找即可。
6.2 即一直出栈,直到出了个高度小于等于【栈顶右边界高度Hr】的柱子 x
,那么 x 就是上面这个矩形的左边界。
出栈到边界了怎么办?在数组开头预备一个0作为栈底标志位结束出栈。
同样压栈到边界了怎么办?在数组结尾预备一个0作为启动出栈的标志位。