100 lines
3.3 KiB
YAML
100 lines
3.3 KiB
YAML
title: Container With Most Water
|
||
slug: container-with-most-water
|
||
difficulty: medium
|
||
leetcode_id: 11
|
||
leetcode_url: https://leetcode.com/problems/container-with-most-water/
|
||
categories:
|
||
- arrays
|
||
- two-pointers
|
||
patterns:
|
||
- two-pointers
|
||
- greedy
|
||
|
||
description: |
|
||
You are given an integer array `height` of length n. There are n vertical lines drawn such
|
||
that the two endpoints of the ith line are (i, 0) and (i, height[i]).
|
||
|
||
Find two lines that together with the x-axis form a container, such that the container
|
||
contains the most water.
|
||
|
||
Return the maximum amount of water a container can store.
|
||
|
||
constraints: |
|
||
- n == height.length
|
||
- 2 <= n <= 10^5
|
||
- 0 <= height[i] <= 10^4
|
||
|
||
examples:
|
||
- input: "height = [1,8,6,2,5,4,8,3,7]"
|
||
output: "49"
|
||
explanation: "Lines at index 1 (height 8) and 8 (height 7) form container with area 7 * 7 = 49."
|
||
- input: "height = [1,1]"
|
||
output: "1"
|
||
explanation: "Only container possible has area 1 * 1 = 1."
|
||
|
||
explanation:
|
||
approach: |
|
||
1. Start with two pointers at the far left and far right
|
||
2. Calculate the area formed by the two lines
|
||
3. Move the pointer pointing to the shorter line inward
|
||
4. Track maximum area seen
|
||
5. Continue until pointers meet
|
||
|
||
intuition: |
|
||
Area = width × height. The height is limited by the shorter line.
|
||
|
||
Starting with maximum width (endpoints), we can only improve by finding taller lines.
|
||
If we move the taller pointer, width decreases and height can't increase beyond the
|
||
shorter line — so area can only decrease or stay the same.
|
||
|
||
Moving the shorter pointer gives us a chance to find a taller line that could
|
||
increase the height enough to compensate for the reduced width.
|
||
|
||
common_pitfalls:
|
||
- title: Moving the wrong pointer
|
||
description: |
|
||
Always move the pointer pointing to the shorter line. Moving the taller one
|
||
cannot possibly increase the area since height is constrained by the shorter.
|
||
wrong_approach: "Moving left pointer always or randomly"
|
||
correct_approach: "Move the pointer with smaller height[i]"
|
||
|
||
- title: Using nested loops
|
||
description: |
|
||
O(n²) brute force is unnecessary. Two pointers achieve O(n) by eliminating
|
||
suboptimal pairs without checking them.
|
||
|
||
key_takeaways:
|
||
- Two pointers from opposite ends is powerful for optimization
|
||
- Moving the limiting factor gives the best chance of improvement
|
||
- Greedy choice (move shorter) is provably optimal here
|
||
- Width × min(heights) is the key formula
|
||
|
||
time_complexity: "O(n)"
|
||
space_complexity: "O(1)"
|
||
complexity_explanation: |
|
||
Time: Each pointer moves at most n times total.
|
||
Space: Only a few variables for pointers and max area.
|
||
|
||
solutions:
|
||
- approach_name: Two Pointers (Optimal)
|
||
is_optimal: true
|
||
code: |
|
||
def max_area(height: list[int]) -> int:
|
||
left, right = 0, len(height) - 1
|
||
max_water = 0
|
||
|
||
while left < right:
|
||
width = right - left
|
||
h = min(height[left], height[right])
|
||
max_water = max(max_water, width * h)
|
||
|
||
if height[left] < height[right]:
|
||
left += 1
|
||
else:
|
||
right -= 1
|
||
|
||
return max_water
|
||
explanation: |
|
||
Start from both ends and move the shorter line inward.
|
||
Track maximum area found during traversal.
|