Title: Find Container with Most Water
In this guide, you will solve one of the most frequently asked array interview problems: finding two lines in a height array that, together with the x-axis, form a container holding the most water. You’ll see the brute-force intuition, the optimal two-pointer approach, a full Java program, and a step-by-step trace so you can explain the logic confidently in an interview.
Understanding the Problem
You are given an array height where height[i] is the height of a vertical line drawn at index i on the x-axis. Choosing any two indices i and j forms a container whose width is the distance between them and whose height is capped by the shorter of the two lines, since water would spill over the shorter wall.
The area of a container is therefore (j - i) * Math.min(height[i], height[j]). The goal is to pick the pair of indices that maximizes this area across the whole array, and return that maximum area as a single integer.
Approach
- Place one pointer
leftat index 0 and another pointerrightat the last index ofheight. - Compute the current width as
right - leftand the current height asMath.min(height[left], height[right]). - Multiply width by height to get the current area, and update
maxAreaif this area is larger. - Compare
height[left]andheight[right]. The shorter line is the bottleneck, so move that pointer inward by one position. - If the two heights are equal, move either pointer inward; the program below moves
rightin that case. - Repeat steps 2 through 5 until
leftandrightmeet, then returnmaxArea.
Java Program
public class ContainerWithMostWater {
public static int maxArea(int[] height) {
int left = 0;
int right = height.length - 1;
int maxArea = 0;
while (left < right) {
int width = right - left;
int currentHeight = Math.min(height[left], height[right]);
int area = width * currentHeight;
maxArea = Math.max(maxArea, area);
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return maxArea;
}
public static void main(String[] args) {
int[] height = {1, 8, 6, 2, 5, 4, 8, 3, 7};
int result = maxArea(height);
System.out.println("Maximum water container area: " + result);
}
}Explanation of the Program
The program walks through the array with two pointers that start at the outer edges and move inward on every step.
leftandrightmark the current candidate pair of lines; they start at the two ends so the first comparison covers the widest possible container.widthis alwaysright - left, the number of index positions between the two lines.currentHeightusesMath.minbecause the container can never hold more water than the shorter wall allows.maxAreakeeps the best area seen so far and is updated withMath.maxon every iteration.- The
if (height[left] < height[right])check decides which pointer moves; the shorter line is discarded because keeping it in place can never produce a larger area than it already has.
Step-by-Step Trace
Consider height = [1, 5, 4, 3, 7, 2]. The two-pointer scan should find a maximum area of 15.
| Iteration | left, right | height[left], height[right] | area | maxArea (before) | maxArea (after) |
|---|---|---|---|---|---|
| 1 | 0, 5 | 1, 2 | 5 | 0 | 5 |
| 2 | 1, 5 | 5, 2 | 8 | 5 | 8 |
| 3 | 1, 4 | 5, 7 | 15 | 8 | 15 |
| 4 | 2, 4 | 4, 7 | 8 | 15 | 15 |
| 5 | 3, 4 | 3, 7 | 3 | 15 | 15 |
At the end of each iteration, maxArea holds the largest area found among every pair examined so far, and the pointer sitting on the shorter line has always moved one step inward.
Examples
Example 1: Two Equal Heights
When both lines are the same height, the area is simply the width times that height, with no shorter wall to cap it further.
public class Example1 {
public static void main(String[] args) {
int[] height = {4, 4};
// Expected output: 4
System.out.println(ContainerWithMostWater.maxArea(height));
}
}With only two lines, width is 1 and currentHeight is 4, so the area is 4.
Example 2: A Dip After Rising Heights
This example shows the two pointers converging after the heights rise and then drop.
public class Example2 {
public static void main(String[] args) {
int[] height = {1, 2, 4, 3};
// Expected output: 4
System.out.println(ContainerWithMostWater.maxArea(height));
}
}The best pair here is index 1 and index 3, giving a width of 2 and a capped height of 2, for an area of 4.
Example 3: All Identical Heights
When every line is the same height, the widest pair always wins because the capped height never changes.
public class Example3 {
public static void main(String[] args) {
int[] height = {5, 5, 5, 5};
// Expected output: 15
System.out.println(ContainerWithMostWater.maxArea(height));
}
}The first comparison uses the full width of 3 and height 5, producing 15, which no narrower pair can beat since the height never grows.
Common Mistakes to Avoid
These are the mistakes candidates most often make when implementing the two-pointer approach for this problem.
- Moving both pointers every iteration - this skips over pairs that could have produced a larger area, such as missing the true maximum on
[1, 8, 6, 2, 5, 4, 8, 3, 7]. Move only the pointer sitting on the shorter line. - Using Math.max instead of Math.min - this computes an area as if water never spills over the shorter wall, giving an impossible result like
8instead of1forheight = {1, 8}. Always cap the height withMath.min(height[left], height[right]). - Computing width as right - left + 1 - this overcounts the distance between the two lines by one unit on every pair, inflating every area slightly. Use
right - left, the true number of positions between the two indices. - Declaring maxArea inside the while loop - resetting
int maxArea = 0on every pass discards all previous comparisons and returns only the last area computed. DeclaremaxAreaonce before the loop starts.
Additional Considerations
The two-pointer scan runs in O(n) time since each iteration moves one pointer inward and the pointers can meet after at most n steps total. It uses O(1) extra space, a clear improvement over a brute-force approach that checks every pair in O(n^2) time.
The approach is correct because moving the pointer on the taller line can never help: the width shrinks, and the height is still capped by the same shorter line that was already compared, so no larger area is reachable by keeping the taller line in place. Discarding the shorter line is always safe, since any wider container that could have used it would have been paired with something at least as tall at the other current position.
Edge Cases to Test
Walk through these input shapes before considering the problem solved.
- Array with fewer than two elements
- Exactly two elements
- All elements equal
- Strictly increasing heights
- Strictly decreasing heights
- Tallest lines at both ends
- Null array reference
Interview Follow-up Questions
Once you have the base solution working, expect an interviewer to push further with questions like these.
- What if you need the actual pair of indices, not just the area? - store
leftandrightalongsidemaxAreawhenever it gets updated, instead of discarding them. - What if the two chosen lines must be no more than K positions apart? - the plain two-pointer scan no longer applies directly; you would need a sliding window combined with a structure that tracks the maximum height within the window.
- What if the heights arrive as a stream and you cannot index backward? - this is a strong signal that the two-pointer technique fundamentally depends on random access to both ends, so you would need to discuss what, if anything, a bounded summary of the stream could still answer.
- Can you do this with O(1) extra space without modifying the input array? - the two-pointer solution already satisfies both constraints, which is exactly why interviewers treat it as the expected optimal answer rather than just one valid approach.
Conclusion
The container with most water problem is a great example of how a two-pointer scan can replace a brute-force O(n^2) search with a single O(n) pass, as long as you can justify why discarding the shorter line is always safe. Once you're comfortable with the pointer movement and the reasoning behind it, the same pattern shows up in many other array problems that ask you to search over all pairs.
Try adapting the program above to return the winning indices instead of just the area, and run it against the edge cases listed earlier until you're confident it handles every shape correctly. You can learn more about array-based interview problems in the Arrays category on this site.



