LeetCode 11 · Two Pointers · Greedy

Container With Most Water

MediumPick two walls that trap the most water — one linear two-pointer pass.
You are given an array height where height[i] is the height of a vertical line at position i. Pick two lines that, together with the x-axis, form a container holding the most water. Return that maximum area. The area between lines i and j is min(height[i], height[j]) × (j − i).

Walkthrough

try:
Each number is a vertical wall. Pick two to hold the most water: area = min(heights) × distance.
10L8162235445863778R
areabest0
pointer wallwater
1
function maxArea(height) {
2
  let left = 0, right = height.length - 1;
3
  let best = 0;
4
  while (left < right) {
5
    const h = Math.min(height[left], height[right]);
6
    const area = h * (right - left);
7
    best = Math.max(best, area);
8
    if (height[left] < height[right]) left++;
9
    else right--;
10
  }
11
  return best;
12
}
left = 0right = 8
step 0 / 42
line 2
Pointers at both ends
Start with the widest possible container: left at the first wall, right at the last.

Intuition

Start as wide as possible: one pointer at each end. Width is largest here, so this is a strong starting candidate.

The water is capped by the SHORTER of the two walls, so the height of the container is min(left, right).

To have any chance of a bigger area you must move a pointer inward — but that shrinks the width. Moving the taller wall can never help (height is still capped by the shorter one), so always move the shorter wall.

Each step discards exactly the wall that can’t do better, so a single pass from both ends finds the maximum in O(n).

The algorithm

  1. 01Put left at 0 and right at the last index; track the best area.
  2. 02Compute area = min(height[left], height[right]) × (right − left) and update best.
  3. 03Move whichever pointer is at the shorter wall one step inward.
  4. 04Repeat until the pointers meet; return best.

Reference implementation

1
function maxArea(height) {
2
  let left = 0, right = height.length - 1;
3
  let best = 0;
4
  while (left < right) {
5
    const h = Math.min(height[left], height[right]);
6
    best = Math.max(best, h * (right - left));
7
    if (height[left] < height[right]) left++;
8
    else right--;
9
  }
10
  return best;
11
}

Complexity

Time
O(n) — each pointer moves inward at most n times.
Space
O(1).