LeetCode ยท #11

Container With Most Water Solution

Given n vertical lines, find two lines that together with the x-axis form a container holding the most water.

01
Section One ยท Problem

Problem Statement

๐Ÿท๏ธ

Difficulty

Medium

๐Ÿ”—

LeetCode

Problem #11

๐Ÿ—๏ธ

Pattern

Two Pointers โ€” move shorter wall

You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the i-th line are (i, 0) and (i, height[i]). Find two lines that, together with the x-axis, form a container that holds the most water. Return the maximum amount of water.

Example
Input: height = [1, 8, 6, 2, 5, 4, 8, 3, 7] Output: 49 // Lines at index 1 (h=8) and index 8 (h=7): min(8,7) ร— (8โˆ’1) = 7 ร— 7 = 49
Constraints
โ€ข n == height.length โ€ข 2 โ‰ค n โ‰ค 10โต โ€ข 0 โ‰ค height[i] โ‰ค 10โด
02
Section Two ยท Approach 1

Brute Force โ€” O(nยฒ)

Try every pair of lines, compute the area for each, and track the maximum. The area formed by lines i and j is min(height[i], height[j]) ร— (j โˆ’ i).

Problem: O(nยฒ) pairs to check. The key insight is that moving the shorter wall inward is the only way to potentially find a larger area โ€” moving the taller wall can never help because the area is limited by the shorter wall.
Java โ€” Brute Force
class Solution { public int maxArea(int[] height) { int max = 0; for (int i = 0; i < height.length; i++) for (int j = i + 1; j < height.length; j++) max = Math.max(max, Math.min(height[i], height[j]) * (j - i)); return max; } }
Python โ€” Brute Force
class Solution: def maxArea(self, height: list[int]) -> int: max_area = 0 for i in range(len(height)): for j in range(i + 1, len(height)): max_area = max(max_area, min(height[i], height[j]) * (j - i)) return max_area
MetricValue
TimeO(nยฒ)
SpaceO(1)
03
Section Three ยท Approach 2

Two Pointers โ€” O(n)

Start with the widest container (pointers at both ends). Compute the area. Then move the pointer pointing to the shorter wall inward โ€” because keeping the shorter wall and reducing width can only make things worse, but moving the shorter wall might find a taller one.

๐Ÿ’ก Mental model: Imagine two walls of a swimming pool. Water level is limited by the shorter wall. If you slide the shorter wall inward, you lose width but might gain height โ€” a worthwhile trade. Sliding the taller wall inward loses width AND can't gain height (still limited by the short wall) โ€” always a loss.
Algorithm
  • Step 1: left = 0, right = n - 1, maxArea = 0.
  • Step 2: Compute area = min(height[left], height[right]) ร— (right โˆ’ left).
  • Step 3: Update maxArea.
  • Step 4: Move the pointer with the smaller height inward.
  • Step 5: Repeat until pointers meet.
๐ŸŽฏ Why moving the shorter wall is correct:
  • The area is min(h_left, h_right) ร— width.
  • If h_left < h_right, then for every position j between left+1 and right, the pair (left, j) has area โ‰ค h_left ร— (j โˆ’ left) < h_left ร— width โ€” always smaller than the current area.
  • So we can safely discard left and move inward. The greedy choice eliminates all provably-suboptimal pairs.
04
Section Four ยท Trace

Visual Walkthrough

Trace through height = [1, 8, 6, 2, 5, 4, 8, 3, 7]:

Two Pointers โ€” move shorter wall inward
HEIGHT ARRAY 1 8 6 2 5 4 8 3 7 L=0,R=8: min(1,7)ร—8 = 8 โ†’ move L (shorter) L=1,R=8: min(8,7)ร—7 = 49 โ† max! โ†’ move R L=1,R=7: min(8,3)ร—6 = 18 โ†’ move R L=1,R=6: min(8,8)ร—5 = 40 โ†’ move L (equal, either works) ... continues narrowing ... max stays 49 Answer: 49 โœ“
05
Section Five ยท Implementation

Code โ€” Java & Python

Java โ€” Two Pointers
class Solution { public int maxArea(int[] height) { int left = 0, right = height.length - 1; int maxArea = 0; while (left < right) { int area = Math.min(height[left], height[right]) * (right - left); maxArea = Math.max(maxArea, area); if (height[left] < height[right]) left++; // move shorter wall else right--; } return maxArea; } }
Python โ€” Two Pointers
class Solution: def maxArea(self, height: list[int]) -> int: left, right = 0, len(height) - 1 max_area = 0 while left < right: area = min(height[left], height[right]) * (right - left) max_area = max(max_area, area) if height[left] < height[right]: left += 1 else: right -= 1 return max_area
06
Section Six ยท Analysis

Complexity Analysis

ApproachTimeSpaceTrade-off
Brute ForceO(nยฒ)O(1)Every pair; too slow for n = 10โต
Two Pointers โ† optimal O(n) O(1) Greedy elimination of suboptimal pairs
07
Section Seven ยท Edge Cases

Edge Cases & Pitfalls

CaseInputWhy It Matters
Two elements[1, 1]Only one pair. Area = min(1,1) ร— 1 = 1.
All same height[5, 5, 5, 5]Max area is at widest pair: 5 ร— 3 = 15.
Descending[5, 4, 3, 2, 1]Right pointer moves inward each time. Max is at start: min(5,1)ร—4=4 or min(5,2)ร—3=6...
Zero heights[0, 2, 0]Any pair with 0 has area 0. Only non-zero pairs matter.
Equal heights[3, 3]When heights are equal, either pointer can move โ€” both discard symmetric candidates.
โš  Common Mistake: Moving the taller wall instead of the shorter one. This is always wrong โ€” moving the tall wall shrinks width while the height stays bottlenecked by the short wall. Only moving the short wall has any chance of increasing area.

โ† Back to Two Pointers problems