Example 1
ready- Input
height = [ 1, 8, 6, 2, 5, 4, 8, 3, 7 ]- Expected
49- Why
- the lines of height 8 and 7 are seven positions apart: 7 × 7 = 49
Two fence posts can trap far more water by standing farther apart — unless one of them is so short that it becomes the leak point. You need the best trade between width and height.
The array height describes vertical lines at positions 0 through
height.length - 1. Pick two different positions i and j, with i < j. Their
container holds this much water:
min(height[i], height[j]) * (j - i)
Return the largest area any pair can hold.
A few details matter:
2 <= height.length <= 100_0000 <= height[i] <= 10_000Hints
Checking every pair is correct. At 100,000 lines, though, that means nearly five billion area calculations.
Put one pointer at each end. After measuring that container, the next width must be smaller. Which of the two lines could you replace and still have a chance to gain height?
Moving the taller line inward keeps the same short wall or finds an even shorter one, while width shrinks. Only replacing the shorter line can possibly improve the limiting height.
Can you explain why moving the shorter line never discards a pair that could beat the current best area?
Visible cases
height = [
1,
8,
6,
2,
5,
4,
8,
3,
7
]49height = [
1,
2,
3,
4,
5
]6height = [
4,
3,
2,
1,
4
]16Interview signal
Treat each line as a possible left wall and pair it with every line to its right. The formula gives the area directly, so keep the largest result seen.
def max_area(height: list[int]) -> int:
best = 0
for left in range(len(height) - 1):
for right in range(left + 1, len(height)):
width = right - left
water_height = min(height[left], height[right])
best = max(best, width * water_height)
return bestTime O(n²) — every pair gets measured. Space O(1) — only the running maximum and loop positions are stored.
Start with the widest possible container: left = 0, right = n - 1. After measuring
it, every future container is narrower. The only possible compensation is a taller
limiting wall.
Suppose the left wall is shorter. Keeping it while moving right inward can't help:
the width shrinks, and the water level can never rise above that unchanged left wall.
So every pair between this left and a smaller right is already beaten by the pair
you just measured. Retire left. The same argument works symmetrically when the right
wall is shorter.
def max_area(height: list[int]) -> int:
left, right = 0, len(height) - 1
best = 0
while left < right:
width = right - left
water_height = min(height[left], height[right])
best = max(best, width * water_height)
if height[left] <= height[right]:
left += 1
else:
right -= 1
return bestTime O(n) — one pointer moves inward on every step, so there are at most n - 1 measurements. Space O(1).
This isn't a lucky greedy move. The shorter wall is a bottleneck — the part that caps the whole result — and the width only gets worse. That proof is what makes one discarded pointer safe.
Ready to run.
3 cases are queued.
Visible testcase
Case 1
Expected
49