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.