Given an array of non-negative integers where each element represents the height of a vertical line on the x-axis, find two lines that together with the x-axis form a container that holds the most water.
This is LeetCode 11, “Container With Most Water”, and it is the problem that taught a generation of candidates the two-pointer pattern. The brute force is O(n²) and obvious. The optimal is O(n) with two pointers, and the invariant — moving the pointer at the shorter line is always correct — is the kind of small but powerful argument that, once internalized, lets a candidate solve dozens of related problems quickly.
Examples
Input: [1,8,6,2,5,4,8,3,7]
Output: 49
Input: [1,1]
Output: 1
The water area for two lines at positions i and j is min(height[i], height[j]) × (j - i) — the shorter line caps the height; the distance between the lines is the width.
Brute force: O(n²)
def max_area_brute(height):
best = 0
for i in range(len(height)):
for j in range(i + 1, len(height)):
area = min(height[i], height[j]) * (j - i)
best = max(best, area)
return best
Try every pair of lines. O(n²) time, O(1) space. Most candidates produce this in 1–2 minutes.
Two pointers: O(n)
def max_area(height):
left, right = 0, len(height) - 1
best = 0
while left < right:
h = min(height[left], height[right])
best = max(best, h * (right - left))
if height[left] < height[right]:
left += 1
else:
right -= 1
return best
Start with pointers at the two ends. Compute the area. Move whichever pointer is at the shorter line. Repeat until the pointers meet.
O(n) time. Each iteration moves one pointer, and the loop terminates when they meet, so total iterations are at most n. O(1) space.
Why moving the shorter side is correct
This is the invariant that makes the algorithm work, and it is the part most candidates struggle with on first encounter.
Suppose height[left] < height[right]. The current container has area height[left] × (right - left). We need to argue that no container with left as one of its endpoints (and any other right endpoint we have not yet considered) can be larger than this current area.
Consider any pair (left, j) with j < right. The area is min(height[left], height[j]) × (j - left). Two cases:
- If
height[j] ≥ height[left], thenmin(height[left], height[j]) = height[left]. The area isheight[left] × (j - left) < height[left] × (right - left)becausej < right. Smaller than current. - If
height[j] < height[left], thenmin(height[left], height[j]) = height[j] < height[left]. The area isheight[j] × (j - left) < height[left] × (right - left). Smaller than current.
Either way, no pair involving left as an endpoint and a smaller right index produces a larger area. So we can safely abandon left and move it inward. The same argument applies symmetrically when height[right] < height[left].
This invariant proof is what most candidates fumble. They produce the algorithm by intuition (or memorization) but cannot articulate why moving the shorter side is correct. A polished candidate produces the proof unprompted, which signals genuine algorithmic depth rather than memorization.
The two-pointer pattern
The two-pointer pattern uses two indices that move toward each other (or both forward) under different conditions, with an invariant that lets the algorithm prune large parts of the search space. The pattern shows up in many problems:
- Container With Most Water (LC 11) — opposite-direction prototype
- Two Sum on Sorted Array (LC 167) — opposite-direction
- 3Sum and 4Sum (LC 15, 18) — outer loop plus opposite-direction inner
- Trapping Rain Water (LC 42) — opposite-direction with invariant
- Remove Duplicates from Sorted Array (LC 26) — same-direction
- Move Zeroes (LC 283) — same-direction
- Sort Colors / Dutch National Flag (LC 75) — three-pointer
- Reverse Vowels of a String (LC 345) — opposite-direction
Container With Most Water is the cleanest first example because the invariant — “move the shorter side” — is short, derivable, and produces a complete O(n) solution. Once a candidate has internalized this problem’s invariant, the related problems become much easier.
What interviewers grade
This is a phone-screen-tier problem (medium difficulty, 30 minutes). The bar is the O(n) solution with the invariant articulated. Signal layers:
- Brute force in 2 minutes. Stating O(n²) is the warmup.
- Recognize the two-pointer opportunity. The candidate articulates that we can avoid recomputing every pair.
- Articulate the invariant. “Move the pointer at the shorter line because no smaller container with that line as an endpoint can be larger.”
- Clean O(n) code. Loop terminates correctly, area computed correctly.
- Edge cases. Single-element array, two-element array, all equal heights.
Is it asked in 2026?
Yes, frequently. Container With Most Water is in the top 50 most-asked LeetCode problems and appears regularly at FAANG phone screens, tier-2 tech onsites, and AI lab interviews. The problem has not aged out because the invariant proof is genuinely interesting and the related two-pointer problems make the question generative — once a candidate solves it well, the interviewer can pivot to 3Sum or trapping rain water as a follow-up.
Frequently Asked Questions
What is the time complexity?
O(n) for the two-pointer solution. Each pointer moves at most n positions in total, so the algorithm performs at most n iterations.
Can I solve it without two pointers?
Yes, with O(n²) brute force. The two-pointer is optimal for this problem; no faster algorithm exists.
What is the relationship to trapping rain water?
Both problems use two pointers and an invariant about which pointer to move. Container with most water finds two lines maximizing area; trapping rain water computes water trapped between all lines. Same technique, different problem framing. Sometimes asked back-to-back.
Why is the invariant correct?
Moving the pointer at the shorter line discards only configurations whose area cannot exceed the current. The proof is short: any container involving the shorter line and a closer second line has both smaller height (or same) and smaller width, so it cannot be larger than the current.
Is this problem still asked in 2026?
Yes, very frequently. It is one of the most-asked LeetCode mediums in tech interviews and remains an excellent introduction to the two-pointer pattern.