const solve = (nums) => { let left = 0, right = nums.length - 1; while (left < right) { const sum = nums[left] + nums[right]; if (sum === target) return [left, right]; }}
Problem Walkthrough

Container With Most Water: LeetCode 11 Solution Explained

The classic two-pointer optimization problem — and one of the top 10 most-asked Medium problems at FAANG companies.

7 min read|

Container With Most Water (#11): two pointers from both ends

Move the shorter line inward — the greedy proof that makes O(n) work

Container With Most Water: Why LeetCode 11 Matters

Container With Most Water (#11) is one of the most-asked Medium problems on LeetCode — and for good reason. It tests whether you can move past brute force and apply the two-pointer pattern to optimize a search over pairs.

If you have seen problems that ask you to find two elements in an array that maximize or minimize some quantity, this is the template problem. Interviewers at Amazon, Google, Meta, and Bloomberg use it as a litmus test for two-pointer fluency.

In this walkthrough you will understand the problem statement, see why brute force fails at scale, learn the O(n) two-pointer solution, and — most importantly — grasp the greedy proof that makes the whole thing work.

Understanding the Container With Most Water Problem

You are given an integer array height of length n. Each element height[i] represents a vertical line drawn at position i on the x-axis. You need to find two lines that, together with the x-axis, form a container that holds the most water.

The area of any container formed by lines at positions i and j is calculated as: Area = min(height[i], height[j]) * (j - i). The minimum of the two heights determines the water level — water would spill over the shorter line. The distance (j - i) is the width.

For example, given height = [1,8,6,2,5,4,8,3,7], the max area is 49, formed by the lines at index 1 (height 8) and index 8 (height 7). The width is 7, the limiting height is 7, so area = 7 * 7 = 49.

The constraint is n up to 100,000. That means any solution slower than O(n log n) will struggle, and the interviewer expects O(n).

ℹ️

Industry Insight

Container With Most Water (#11) is a top 10 most-asked Medium problem — it appears at Amazon, Google, Meta, and Bloomberg as a go-to two-pointer assessment.

Brute Force — Check Every Pair

The most straightforward approach is to check every possible pair of lines. For each pair (i, j), compute the area and track the maximum. This guarantees you find the answer because you literally try everything.

The code is simple: two nested loops, an area calculation inside, and a running maximum. For the example above it works perfectly and returns 49.

The problem is time complexity. With two nested loops over n elements, the brute force runs in O(n^2). When n = 100,000, that is 10 billion operations — far too slow for a typical 1-2 second time limit.

Interviewers expect you to identify this inefficiency and propose the linear solution. The brute force is a fine starting point in a conversation, but you need to move beyond it quickly.

  • Time complexity: O(n^2) — every pair of indices is checked
  • Space complexity: O(1) — only tracking the max area
  • Works for small inputs but times out when n exceeds a few thousand

Two Pointer Solution for Container With Most Water

The key insight is that you do not need to check every pair. Start with two pointers: left at index 0 and right at index n - 1. Compute the area for this pair. Then move the pointer that points to the shorter line inward by one step. Repeat until the pointers meet.

Why does this work? At each step you are guaranteed to have the maximum possible width for the current pair. By moving the shorter pointer inward, you sacrifice width but gain the chance of a taller line — which is the only way the area could increase. Moving the taller pointer can never help because the bottleneck (the shorter line) stays the same while the width decreases.

Here is the algorithm in pseudocode: initialize left = 0, right = n - 1, maxArea = 0. While left < right, compute area = min(height[left], height[right]) * (right - left). Update maxArea. If height[left] < height[right], increment left. Otherwise, decrement right.

This runs in O(n) time and O(1) space. You visit each element at most once. Five lines of code for a problem that stumps candidates who do not know the pattern.

  • Time complexity: O(n) — each pointer moves at most n steps total
  • Space complexity: O(1) — just two pointers and a max tracker
  • The entire algorithm fits in 5-7 lines of actual code
💡

Pro Tip

The entire algorithm: left=0, right=n-1. While left < right: compute area, move the pointer with the shorter height. That's it — 5 lines of code for an O(n) solution.

Why Moving the Shorter Line Is Optimal — The Greedy Proof

This is the part most walkthroughs skip, but it is the heart of the problem. Why is it safe to discard all pairs involving the shorter line at its current position?

Consider the state where left points to a shorter line than right. Every pair (left, k) where k < right has a smaller width than (left, right). The height is still bounded by height[left] because it is the shorter side. So area = min(height[left], height[k]) * (k - left) is at most height[left] * (k - left), which is strictly less than height[left] * (right - left). No pair involving the current left with any index less than right can beat the current area.

By contradiction: suppose the optimal container uses the current shorter line paired with some index between left and right. That container would have both smaller width and the same height bottleneck — impossible to beat the area we already computed.

This is why the greedy approach is correct. At every step, you eliminate a pointer that provably cannot participate in a better solution. The algorithm explores all potentially optimal pairs without explicitly enumerating them.

Edge Cases for Container With Most Water

While the two-pointer approach handles all cases uniformly, it helps to think through edge scenarios for interview discussions and to verify your understanding.

Two elements: when the array has exactly two elements, there is only one container. The algorithm computes its area in a single iteration. No special handling needed.

All same height: if every line has the same height h, the maximum area is h * (n - 1), formed by the first and last lines. The algorithm naturally finds this because both pointers move inward symmetrically and the first computation is already the answer.

Strictly decreasing or increasing: for a sorted array like [5,4,3,2,1], the widest container is often the best because the tallest lines are at opposite ends. The two-pointer approach checks the widest pair first, which is exactly what you want.

  • Two elements — only one possible container, trivially solved
  • All same height — max area is height * (n - 1)
  • Strictly increasing or decreasing — widest container tends to win
  • Very large n (100,000) — O(n) handles it comfortably

What Container With Most Water Teaches You

Container With Most Water is the textbook example of the "squeeze from both ends" two-pointer pattern. Unlike the two-pointer pattern for sorted arrays (like Two Sum II), this one works on unsorted input. The deciding factor for which pointer to move is not about maintaining a sort invariant — it is about eliminating the bottleneck.

This pattern shows up in several related problems. Three Sum and Four Sum use sorted two pointers. Trapping Rain Water (#42) looks similar on the surface but is a completely different problem — #42 calculates water trapped between all bars using a stack or left-right max arrays, while #11 finds the single largest rectangle between two lines.

If you are preparing for interviews, practice Container With Most Water until the greedy proof feels intuitive. Use YeetCode flashcards to drill the pattern: "two lines, move the shorter one" should become automatic recall.

The next time you see a problem asking you to maximize or minimize something over pairs in an array, ask yourself: can I start from both ends and eliminate one side at each step? If the answer is yes, you have an O(n) solution waiting to be written.

⚠️

Common Confusion

Don't confuse Container With Most Water (#11) with Trapping Rain Water (#42) — #11 finds the largest rectangle between two lines, while #42 calculates water trapped between ALL bars. Completely different problems.

Ready to master algorithm patterns?

YeetCode flashcards help you build pattern recognition through active recall and spaced repetition.

Start practicing now