Start at the widest pair and move the shorter wall inward. Width only shrinks, so only a taller wall can help.
Two walls hold water up to the shorter of the two, over the distance between them. Start with the widest possible pair and walk inward from the shorter side. Width only ever shrinks, so the only way to beat the current area is to find a taller wall.
Place left at index 0 and right at the last index. The area they hold is (right − left) × min(height[left], height[right]). Record it, then move the SHORTER wall inward. Keeping it can never help, because width is about to shrink and that wall already caps the height.
Suppose the left wall is the shorter one. Any pair still containing that left wall must have a smaller width than the pair you just measured, and its height is still capped by that same short wall. So every remaining pair using it is strictly worse, so discarding it loses nothing.
For [1,8,6,2,5,4,8,3,7]: the widest pair gives 8, then the pointers close in until they meet. The best container turns out to be between index 1 (h=8) and index 8 (h=7), holding 7 × 7 = 49.
Each iteration moves exactly one pointer inward, so the two pointers together cover the array once, so the time is O(n). Only a handful of scalars are tracked, so the space is O(1). The brute force over every pair would be O(n²).
Note that the walls have no thickness and the ground is flat. This is not Trapping Rain Water, where every bar traps water on top of it. Here only two walls matter at a time, and the greedy "move the shorter wall" exchange argument is what makes the single pass provably correct.