Container With Most Water in DSA Go - Time & Space Complexity
We want to understand how the time needed to find the container with the most water changes as the number of lines grows.
How does the number of steps grow when we have more lines to check?
Analyze the time complexity of the following code snippet.
func maxArea(height []int) int {
left, right := 0, len(height)-1
maxArea := 0
for left < right {
width := right - left
var h int
if height[left] < height[right] {
h = height[left]
left++
} else {
h = height[right]
right--
}
area := width * h
if area > maxArea {
maxArea = area
}
}
return maxArea
}
This code finds the largest area between two lines by moving pointers from both ends towards the center.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop moving two pointers inward.
- How many times: The loop runs at most once for each element, so about n times where n is the number of lines.
As the number of lines increases, the steps grow 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 steps increase linearly with input size.
Time Complexity: O(n)
This means the time to find the largest container grows in direct proportion to the number of lines.
[X] Wrong: "Checking every pair of lines is needed, so time is O(n²)."
[OK] Correct: The two-pointer method smartly skips unnecessary pairs, so it only needs to check each line once.
Understanding this approach shows you can optimize by avoiding needless checks, a key skill in problem solving.
"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 ask you to find given an array of heights?Solution
Step 1: Understand the problem statement
The problem asks to find two lines which together with the x-axis form a container that holds the most water.Step 2: Identify what to calculate
We calculate the area between two lines as the width between them times the smaller height.Final Answer:
The maximum area of water that can be contained between two lines -> Option CQuick Check:
Container with most water = maximum area [OK]
- Confusing max area with sum of heights
- Ignoring the smaller height when calculating area
- Thinking about counting lines instead of area
Solution
Step 1: Recall Go slice declaration syntax
In Go, slices are declared using []type{values}, for example []int{1,2,3}.Step 2: Check each option
heights := []int{1, 8, 6, 2, 5, 4, 8, 3, 7} uses []int{...} which is correct. Options A, B, C use invalid syntax for slices.Final Answer:
heights := []int{1, 8, 6, 2, 5, 4, 8, 3, 7} -> Option AQuick Check:
Slice declaration uses []type{values} [OK]
- Using parentheses or braces instead of [] for slices
- Confusing arrays and slices syntax
- Missing type declaration in slice
package main
import "fmt"
func maxArea(height []int) int {
left, right := 0, len(height)-1
maxArea := 0
for left < right {
width := right - left
var h int
if height[left] < height[right] {
h = height[left]
left++
} else {
h = height[right]
right--
}
area := width * h
if area > maxArea {
maxArea = area
}
}
return maxArea
}
func main() {
heights := []int{1,8,6,2,5,4,8,3,7}
fmt.Println(maxArea(heights))
}Solution
Step 1: Understand the two-pointer approach
Start with left=0 and right=8, calculate area and move the pointer with smaller height inward.Step 2: Trace the iterations
Initial area: min(1,7)*8=8 Move left to 1 Next area: min(8,7)*7=49 Move right to 7 Next area: min(8,3)*6=18 Move right to 6 Next area: min(8,8)*5=40 Move right to 5 Next area: min(8,4)*4=16 Move right to 4 Next area: min(8,5)*3=15 Move right to 3 Next area: min(8,2)*2=4 Move right to 2 Next area: min(8,6)*1=1 Move left to 2 Max area found is 49.Final Answer:
49 -> Option AQuick Check:
Max area calculated by two-pointer = 49 [OK]
- Calculating area with max height instead of min
- Not moving the pointer with smaller height
- Confusing width calculation
func maxArea(height []int) int {
left, right := 0, len(height)-1
maxArea := 0
for left <= right {
width := right - left
var h int
if height[left] < height[right] {
h = height[left]
left++
} else {
h = height[right]
right--
}
area := width * h
if area > maxArea {
maxArea = area
}
}
return maxArea
}Solution
Step 1: Analyze the loop condition
The loop runs while left <= right, which allows left and right to be equal, causing width to be zero or negative.Step 2: Fix the loop condition
Changing to left < right ensures width is always positive and valid for area calculation.Final Answer:
Change loop condition to 'left < right' instead of 'left <= right' -> Option DQuick Check:
Loop must run while left < right [OK]
- Using <= instead of < causing invalid area
- Updating both pointers at once
- Not checking if area is greater before updating maxArea
[]int{4, 3, 2, 1, 4}, what is the maximum water container area? Use the two-pointer approach and explain why the maximum area is found at those positions.Solution
Step 1: Initialize pointers and calculate areas
Start with left=0 (height=4), right=4 (height=4), width=4, area=4*4=16.Step 2: Move pointers and check other areas
Since heights[left] == heights[right], move right pointer left: Now left=0, right=3 (height=1), width=3, area=min(4,1)*3=3 Move right to 2 (height=2), area= min(4,2)*2=4 Move right to 1 (height=3), area= min(4,3)*1=3 Max area remains 16.Final Answer:
16 -> Option BQuick Check:
Max area between positions 0 and 4 = 16 [OK]
- Not considering both ends first
- Moving wrong pointer when heights are equal
- Calculating area incorrectly with wrong width
Ready to prove it?
Pass the test and this pattern moves unknown
