这道题算是真的很难的一道题目,但是不明白为什么会被归在stack的分类下,我觉得应该归在math的分类下。
这道题的难点在于不能确定哪里开始装水,装水的高度多少。而这一切,并不能全部依靠代码解决,仍然需要我们对装水规律进行归纳,从而得出方法。
我们发现的第一条规律是,水从最左边(右边)开始第一个出现下降趋势的柱子才可能开始储水,比如给定数组是{1,2,3,3,2,1,2,3,1,4,5,2,1},则从左往右看,一定是从第五根柱子2开始才可能储水,而从右往左看,则一定是从第四根柱子4开始才可能储水的。
第二条规律则是,当有可能开始储水的那条柱子接下来会出现高于等于它的柱子时,它就真正的开始储水,且它外面的一根柱子作为容器的一条边,而此时容器(即两边高中间低的一个子数组)内的水面高度为较低边的高度(即我们说的开始储水的柱子外面的一根柱子)。
第三条规律是,从两边开始执行遍历,当发现一个容器后将容器移除,则剩下部分继续进行遍历操作时以上两天规律依然成立。
因此,我们这道题的做法是同时从两边开始遍历,先找到开始出现下降趋势的柱子,并将其上一根柱子(外面的柱子)作为容器的一条边。此时还要将左右作为容器边的两根柱子进行比较,比较小的一根柱子则可以作为它所在容器的水面高度(若有一边还没出现边则与正在遍历的柱子进行比较,因为比较后是小的一方成为水面高度,所以若出现一条边小于一根不是边的柱子,则说明比正在遍历的柱子还要高的那条边一定比那条相对较小的边大)。得到容器水面后,则容器内每一根柱子上方的水容量都可以得到。当我们得到一个完整容器后,就将之置之不理,继续重复上述操作。
代码如下: