Container With Most Water in DSA C++ - Time & Space Complexity
We want to understand how the time needed to find the container with the most water grows as the number of lines increases.
How does the number of operations change when we have more lines to check?
Analyze the time complexity of the following code snippet.
int maxArea(std::vector<int>& height) {
int left = 0, right = height.size() - 1;
int max_area = 0;
while (left < right) {
int width = right - left;
int area = std::min(height[left], height[right]) * width;
max_area = std::max(max_area, area);
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return max_area;
}
This code finds the maximum water container by moving two pointers from both ends towards the center.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves the left and right pointers towards each other.
- How many times: At most, the loop runs once for each element, so about n times where n is the number of lines.
As the number of lines increases, the number of loop steps grows roughly the same as the number of lines.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The operations grow linearly with input size.
Time Complexity: O(n)
This means the time to find the max water container grows in direct proportion to the number of lines.
[X] Wrong: "Because there are two pointers, the time complexity is O(n²) since we check pairs."
[OK] Correct: The pointers move inward only once each, so total steps are just n, not n squared.
Understanding this linear time approach shows you can optimize from a naive double loop to a smart two-pointer method, a valuable skill in interviews.
"What if we used a nested loop to check all pairs instead of two pointers? How would the time complexity change?"
Practice
Container With Most Water problem?Solution
Step 1: Understand the problem statement
The problem asks to find two vertical lines which, together with the x-axis, form a container that holds the maximum amount of water.Step 2: Identify what is being maximized
The area between two lines is calculated by the minimum height of the two lines multiplied by the distance between them. We want to maximize this area.Final Answer:
Find two lines that together with the x-axis form a container holding the most water -> Option AQuick Check:
Goal = Max water container [OK]
- Thinking it's about sorting heights
- Trying to sum heights instead of area
- Looking for max single height only
Solution
Step 1: Understand pointer initialization
We start with two pointers: one at the beginning (index 0) and one at the end (index size-1) of the array.Step 2: Check each option
int left = 0, right = heights.size() - 1; correctly sets left = 0 and right = size - 1, which are valid indices. Other options use invalid indices or off-by-one errors.Final Answer:
int left = 0, right = heights.size() - 1; -> Option BQuick Check:
Pointers start at ends = int left = 0, right = heights.size() - 1; [OK]
- Using size() as index (out of bounds)
- Starting pointers at 1 instead of 0
- Swapping left and right initialization
std::vector<int> heights = {1, 8, 6, 2, 5, 4, 8, 3, 7};
int left = 0, right = heights.size() - 1;
int maxArea = 0;
while (left < right) {
int height = std::min(heights[left], heights[right]);
int width = right - left;
maxArea = std::max(maxArea, height * width);
if (heights[left] < heights[right]) {
left++;
} else {
right--;
}
}
std::cout << maxArea << std::endl;Solution
Step 1: Trace the two-pointer approach
Start with left=0 (height=1), right=8 (height=7), area= min(1,7)*8=8. Move left pointer since height[left]Step 2: Continue updating maxArea
Next left=1 (8), right=8 (7), area= min(8,7)*7=49 (maxArea=49). Move right pointer since height[left]>height[right]. Then left=1, right=7 (3), area= min(8,3)*6=18 (maxArea=49). Move right pointer. Continue similarly until pointers meet. The maximum area found is 49.Final Answer:
49 -> Option DQuick Check:
Max area = 49 [OK]
- Not updating maxArea correctly
- Moving wrong pointer after comparison
- Calculating area with max height instead of min
int maxArea(std::vector<int>& heights) {
int left = 0, right = heights.size();
int max_area = 0;
while (left < right) {
int height = std::min(heights[left], heights[right]);
int width = right - left;
max_area = std::max(max_area, height * width);
if (heights[left] < heights[right]) {
left++;
} else {
right--;
}
}
return max_area;
}Solution
Step 1: Check pointer initialization
right is initialized to heights.size(), which is out of bounds since valid indices go up to size()-1.Step 2: Correct initialization and loop condition
right should be heights.size() - 1 to point to the last valid element. The loop condition left < right is correct.Final Answer:
right should be initialized to heights.size() - 1 -> Option CQuick Check:
Index out of bounds fixed by right should be initialized to heights.size() - 1 [OK]
- Using size() as index causing runtime error
- Changing loop condition incorrectly
- Using max instead of min for height
Solution
Step 1: Understand zero height impact
Lines with zero height cannot hold water, so including them wastes time and area calculations.Step 2: Modify two-pointer approach
Skip zero height lines by moving pointers inward until both point to non-zero heights. Then apply the standard two-pointer logic to maximize area.Final Answer:
Skip zero height lines by moving pointers inward until non-zero heights are found -> Option AQuick Check:
Skip zeros for max area [OK]
- Processing zero height lines as normal
- Removing elements changes indices and complicates logic
- Switching to nested loops loses efficiency
Ready to prove it?
Pass the test and this pattern moves unknown
