这个问题可以在线性时间内解决。
构造一个可能的左墙列表(位置+高度对),按从高到低的顺序排列。这是通过获取最左边的可能墙并将其添加到列表中来完成的,然后从左到右遍历所有可能的墙,并获取所有大于添加到列表中的最后一堵墙的墙。例如,对于数组
2 5 4 7 3 6 2 1 3
你可能的左墙将是(对是(pos,val)):
(3, 7) (1, 5) (0, 2)
以相同的方式构建可能的右墙列表,但从右到左。对于上面的数组,可能的右墙是:
(3, 7) (5, 6) (8, 3)
开始你的水位尽可能高,这是两个列表前面墙壁的最小高度。使用这些墙壁计算水的总体积(它可能是负数或零,但没关系),然后通过从其中一个列表中弹出一个元素来降低水位,以使水位下降最少。计算每个高度的可能水量并取最大值。
在这些列表上运行此算法将如下所示:
L: (3, 7) (1, 5) (0, 2) # if we pop this one then our water level drops to 5
R: (3, 7) (5, 6) (8, 3) # so we pop this one since it will only drop to 6
Height = 7
Volume = (3 - 3) * 7 = 0
Max = 0
L: (3, 7) (1, 5) (0, 2) # we pop this one now so our water level drops to 5
R: (5, 6) (8, 3) # instead of 3, like if we popped this one
Height = 6
Volume = (5 - 3) * 6 = 12
Max = 12
L: (1, 5) (0, 2)
R: (5, 6) (8, 3)
Height = 5
Volume = (5 - 1) * 5 = 20
Max = 20
L: (1, 5) (0, 2)
R: (8, 3)
Height = 3
Volume = (8 - 1) * 3 = 21
Max = 21
L: (0, 2)
R: (8, 3)
Height = 2
Volume = (8 - 0) * 2 = 16
Max = 21
步骤 1、2 和 3 都以线性时间运行,因此完整的解决方案也需要线性时间。