Given an integer array height, where height[i] represents the height of a vertical line drawn at index i, find the maximum amount of water that can be contained between any two lines.
The water container is formed by choosing two lines, and the amount of water depends on the shorter line and the distance between the two lines.
Return the maximum water that can be stored.
Example 1
Input: height = [1, 5, 4, 3]
Output: 6
Explanation: The maximum water is formed between the line at index 1 with height 5 and the line at index 3 with height 3. The width is 3 - 1 = 2, and the limiting height is 3. So, water stored = 2 * 3 = 6.

Example 2
Input: height = [1, 1]
Output: 1
Explanation: The only possible container is formed by both lines. Width = 1 and height = 1, so water stored = 1.
Example 3
Input: height = [4, 3, 2, 1, 4]
Output: 16
Explanation: The best container is formed between index 0 and index 4. Width = 4 and limiting height = 4, so water stored = 16.
Brute Force Approach
Any two different lines can form a container. Checking every possible pair guarantees examination of every possible water area.
For selected indices i and j, distance j - i provides container width. The smaller boundary provides water level because water above the shorter line would overflow. Maximum area across all pairs becomes the required answer.
Algorithm
Return 0 when height contains fewer than two values because container formation requires two boundaries.
Initialize maxWater with 0 for storing the largest water area found during pair examination.
Traverse index i from 0 to N - 2 and select
height[i]as the left boundary.Traverse index j from i + 1 to N - 1 and select
height[j]as the right boundary.Calculate width as
j - i, containerHeight asmin(height[i], height[j]), and currentWater aswidth × containerHeight.Update maxWater with the larger value between maxWater and currentWater, then return maxWater after all pairs receive examination.
Dry Run
Container With Most Water Brute Force Dry Run.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: long long maxArea(vector<int>& height) { int n = height.size(); // Two lines are required to form a container. if (n < 2) { return 0; } long long maxWater = 0; /* * Check every pair of lines as * possible container boundaries. */ for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { long long width = j - i; // The shorter line limits the water height. long long containerHeight = min(height[i], height[j]); long long currentWater = width * containerHeight; // Keep the largest container area found so far. if (currentWater > maxWater) { maxWater = currentWater; } } } return maxWater; }};int main() { vector<int> height = {1, 5, 4, 3}; Solution solution; cout << solution.maxArea(height) << endl; return 0;}Complexity Analysis
Time Complexity: O(N²), where N represents the number of lines. Every possible pair of indices may be examined.
Space Complexity: O(1), because only loop indices, area-related variables, and maxWater require auxiliary storage.
Optimal Approach
Start with the two outermost lines because they provide the maximum possible width.
For the current pair, the shorter line limits the container height. If that shorter line is kept and the taller line is moved inward, the width decreases while the limiting height cannot improve, so that choice cannot produce a better area.
Therefore, move the pointer at the shorter line. Although the width becomes smaller, finding a taller boundary is the only way the new container can possibly have a larger area.
This lets us discard one boundary after every comparison and find the answer in a single traversal. This is the standard two-pointer elimination used for the problem
Algorithm
Return
0when fewer than two heights are available because a container requires two boundaries.Initialize
left = 0andright = N - 1so the first pair gives the maximum available width. InitializemaxWater = 0.While
left < right, calculate the current width asright - leftand the usable height asmin(height[left], height[right]).Multiply the width and usable height to obtain the current container area, then update
maxWaterif this area is larger.If
height[left] < height[right], incrementleftbecause the left boundary is limiting the water height. Otherwise, decrementrightbecause the right boundary is the limiting boundary.Continue until the pointers meet, then return
maxWater.
Dry Run
Container With Most Water Optimal Approach Dry Run.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: long long maxArea(vector<int>& height) { int n = height.size(); // Two lines are required to form a container. if (n < 2) { return 0; } int left = 0; int right = n - 1; long long maxWater = 0; while (left < right) { long long width = right - left; // The shorter boundary limits the water level. long long containerHeight = min(height[left], height[right]); long long currentWater = width * containerHeight; // Keep the largest container area found so far. if (currentWater > maxWater) { maxWater = currentWater; } /* * Move the shorter boundary because keeping it * while reducing width cannot improve the area. */ if (height[left] < height[right]) { left++; } else { right--; } } return maxWater; }};int main() { vector<int> height = {1, 5, 4, 3}; Solution solution; cout << solution.maxArea(height) << endl; return 0;}Complexity Analysis
Time Complexity: O(N), where N represents the number of lines. At every step, either left moves forward or right moves backward, so each pointer moves at most N positions.
Space Complexity: O(1), because only two pointers and a constant number of area-related variables require auxiliary storage.
FAQs
Q1. Why does the shorter boundary determine the water level?
Water above the shorter boundary would overflow. Therefore, the usable container height is always min(height[left], height[right]).
Q2. Why does the Optimal Approach move the shorter boundary?
Keeping the shorter boundary while reducing the width cannot improve the area because the same short line would continue limiting the height. Moving it is the only choice that may discover a taller limiting boundary.
Q3. Why can the intermediate lines be ignored?
The problem asks us to choose two lines that, together with the x-axis, form the container. Its capacity depends only on the distance between those selected lines and the shorter selected boundary; intermediate lines do not become additional container walls.
Q4. Can both pointers move when both boundary heights are equal?
Yes. Either boundary may be discarded because both currently impose the same limiting height. A standard implementation usually moves one of them to keep the logic simple.
Q5. How should overflow be prevented for large constraints?
Use a sufficiently wide numeric type for width × containerHeight, such as long long in C++ or long in Java, when the constraints can produce values beyond the 32-bit integer range.
Be the first to add a comment.