None of the 17 responses already published are optimal in time.
For one processor, fetching 2 sweeps ( left->right , followed by summing right->left ) is optimal, as many people have pointed out, but using many processors, you can perform this task in O (log n). There are many ways to do this, so I will explain one that is close enough to a sequential algorithm.
Maximum Cached Tree O (log n)
1: Create a binary tree of all the towers so that each node contains the height of the highest tower of any of its children. Since two sheets of any node can be calculated independently, this can be done in O(log n) time with n cpu's.
2a: Then for each node in the tree, starting from the root, let the right leaf be set to max(left, self, right) . This will create a monotonic sweep from left to right in O(log n) using n cpu.
2b: To calculate the scroll from right to left, we follow the same procedure as before. Starting from the root of the tree with the maximum cache, let the left leaf be set to max(left, self, right) . These arrows from left to right (2a) and from right to left (2b) can be executed in parallel if you want. They both use the maximum cached tree as input and generate one new tree each (or set their own fields in the source tree if you prefer this).
3: Then for each tower the amount of water on it min(ltr, rtl) - towerHeight , where ltr is the value of this tower in the monotonous scan from left to right, which we did before, that is, the maximum height is any tower to our left (including us 1 ) , and rtl same for the arrow from right to left.
4: just summarize this using the tree in O(log n) using n cpu and we are done.
1 If the current tower is above all the towers to our left or above all the towers to our right, min(ltr, rtl) - towerHeight is zero.
Here are two other ways to do this .
Filip Haglund Dec 09 '16 at 20:15 2016-12-09 20:15
source share