Container With Most Water and the Greedy Pointer Proof
If you interview at Google, Amazon, Bloomberg, expect some version of "Container With Most Water". It is rated Medium, and it falls squarely into the Two Pointers pattern — pattern-first preparation beats grinding random problems every time. Part 6 of 12 in the Two Pointers arc.
The Problem
You are given height, where height[i] is the height of a vertical line at position i. Choose two lines that, with the x-axis, form a container holding the most water. Return the maximum area. Width times the shorter height — and n can be 100,000, so the O(n²) pair scan is off the table.
Input: height = [1, 8, 6, 2, 5, 4, 8, 3, 7]
Output: 49
Lines at indices 1 and 8: min(8, 7) * (8 - 1) = 49.
Recognizing the Two Pointers Pattern
Two pointers means walking a sequence with two indices that move based on a comparison — from both ends inward, or slow-and-fast in one direction. It turns brute-force pair scans that cost O(n²) into a single O(n) pass, and it is usually the intended answer whenever the input is sorted or can be sorted cheaply.
Maximizing a function of a pair under a size constraint, where moving inward only shrinks width, is prime converging-pointer territory. The interview is really about the elimination argument — why moving the shorter line never discards the optimum.
The Approach
Start at both ends — maximum width — and record the area. The shorter line caps the area, and keeping it while shrinking width can only do worse: every container using the shorter line with any nearer partner is strictly smaller. So the shorter side is exhausted and its pointer moves inward.
That is a proof by elimination, not a heuristic. Being able to say why the greedy move is safe is the difference between a hire and a lean-hire on this question.
Python Solution
def max_area(height: list[int]) -> int:
"""Largest water area between any two lines."""
left, right = 0, len(height) - 1
best = 0
while left < right:
area = min(height[left], height[right]) * (right - left)
best = max(best, area)
if height[left] < height[right]:
left += 1 # left line exhausted: nothing better uses it
else:
right -= 1
return best
Complexity
- Time: O(n) — one pointer moves inward per iteration
- Space: O(1) — constant state: two pointers and a running best
Interview Tips and Follow-Ups
- Rehearse the elimination proof in one breath — it is the single most-probed line of reasoning in this problem.
- On ties, moving either pointer is correct; say so instead of hedging.
- Do not confuse this with Trapping Rain Water (end of this arc) — different model, and naming the difference impresses.
If this clicked, continue the Two Pointers arc in the Technical Interview category. One hundred questions, nine patterns, all in Python.
Keep reading
Backspace String Compare Backwards in Constant Space
Compare typed strings with backspaces in O(1) space, scanning backwards. Python solution and complexity analysis for the two pointers interview pattern.
Move Zeroes: In Place Partitioning With a Write Pointer
Push all zeroes to the back in one pass, preserving order. Python solution and complexity analysis for the two pointers interview pattern.
Remove Duplicates In Place: The Reader Writer Pointer Trick
Dedupe a sorted array in place with a reader and a writer index. Python solution and complexity analysis for the two pointers interview pattern.
Newsletter
New posts, straight to your inbox
One email per post. No spam, no tracking pixels, unsubscribe anytime.
Comments
- No comments yet. Be the first.