Approach Summary
Start with widest container. Move the pointer with the shorter height inward — the wider pointer cannot improve the container area.
Full Solution & Approach
The area between two lines is width times the shorter height, so the area is limited by the smaller of the two heights. Start with the widest possible container — the two ends. Compute its area and record it. The key insight: moving the taller line inward can never improve the area, because the width shrinks while the height is still capped by the shorter line. So always move the pointer pointing at the shorter line. This greedy is optimal because every configuration where the shorter line participates is evaluated before that line is abandoned, and every abandoned pair is provably worse than a pair already considered. Keep updating the best area until the pointers meet. This is the canonical two-pointer convergence problem and the reasoning — eliminate the pointer that cannot be part of a better answer — generalizes to several hard problems.
Each step moves exactly one pointer, so the pointers cross after at most n steps — O(n) time. Constant extra space — O(1).
Solution Code
Solution
def max_area(height: list[int]) -> int:
left, right = 0, len(height) - 1
best = 0
while left < right:
best = max(best, (right - left) * min(height[left], height[right]))
if height[left] < height[right]:
left += 1
else:
right -= 1
return bestfunction maxArea(height) {
let left = 0, right = height.length - 1;
let best = 0;
while (left < right) {
best = Math.max(best, (right - left) * Math.min(height[left], height[right]));
if (height[left] < height[right]) left++;
else right--;
}
return best;
}public int maxArea(int[] height) {
int left = 0, right = height.length - 1;
int best = 0;
while (left < right) {
best = Math.max(best, (right - left) * Math.min(height[left], height[right]));
if (height[left] < height[right]) left++;
else right--;
}
return best;
}int maxArea(const vector<int>& height) {
int left = 0, right = (int)height.size() - 1;
int best = 0;
while (left < right) {
best = max(best, (right - left) * min(height[left], height[right]));
if (height[left] < height[right]) left++;
else right--;
}
return best;
} Edge Cases to Watch
- All heights equal — area is the full width times the height
- Two elements — the only container is the pair itself
- Very tall line with a short line — the short line caps the area
- Minimum height at the middle — the wide sides still produce large areas
How to Recognize This Pattern
- Max area between two heights
- Pointer convergence
Complexity Analysis
Time Complexity
O(n)
Space Complexity
O(1)