Editorial solutions and visualizations are prepared with care, but we do not guarantee 100% accuracy or completeness. Please use your own judgment to verify results. Visucodize is not responsible for decisions made based on this content.
Solution code
constLEFT='left',LEFT_COLOR='orange';constRIGHT='right',RIGHT_COLOR='blue';functionvisMainFunction(inputHeight){initClassProperties();startBatch();const height = VisArray.from(inputHeight).options({renderingStyle: RenderingStyle.BAR_CHART});let left =0;let right = height.length -1;let maxWater =0;makeVisVariable(left).registerAsIndexPointer(height,LEFT);makeVisVariable(right).registerAsIndexPointer(height,RIGHT);makeVisVariable(maxWater).options({label:'maxWater'}).createVis(true);endBatch();explanationAndColorPaletteNotifications();notification(`
🏗️ <b>Initialization:</b><br/>
• ${makeColoredSpan('left',LEFT_COLOR)} = 0<br/>
• ${makeColoredSpan('right',RIGHT_COLOR)} = n − 1<br/>
• <b>maxWater</b> = 0<br/><br/>
🔄 <b>Loop:</b> While ${makeColoredSpan('left',LEFT_COLOR)} < ${makeColoredSpan('right',RIGHT_COLOR)}:<br/>
• Measure current container (width × min height).<br/>
• Update <b>maxWater</b> if larger.<br/>
• Move the <b>shorter (or equal) side</b> to try replacing it with a taller one.<br/><br/>
⏳ Since the window strictly shrinks each step, the loop always terminates after at most <code>n − 1</code> iterations.
`);while(left < right){startPartialBatch();const width = right - left;const minHeight = Math.min(height[left], height[right]);const currentWater = width * minHeight;notification(`
📌 Checking container between
index <b>${makeColoredSpan(left,LEFT_COLOR)}</b> (height <b>${makeColoredSpan(height[left],LEFT_COLOR)}</b>) and
index <b>${makeColoredSpan(right,RIGHT_COLOR)}</b> (height <b>${makeColoredSpan(height[right],RIGHT_COLOR)}</b>).
`);notification(`
🔎 <b>Width</b> = <code>${width}</code>,
<b>min height</b> = <code>${minHeight}</code>,
<b>current area</b> = <code>${currentWater}</code>.
`);if(currentWater > maxWater){notification(`✅ <b>New maximum</b> area found: <code>${currentWater}</code> (previous <code>${maxWater}</code>).`);
maxWater = currentWater;}if(height[left]< height[right]){notification(`
➡️ ${makeColoredSpan('left',LEFT_COLOR)} is the <b>shorter</b> side
(<b>${makeColoredSpan(height[left],LEFT_COLOR)}</b> vs <b>${makeColoredSpan(height[right],RIGHT_COLOR)}</b>).<br/>
Being the <b>shorter side</b> makes it a <b>bottleneck</b> for height, and width will never expand back (it only shrinks with each move).
Therefore, keeping it cannot yield a larger area.
👉 Move ${makeColoredSpan('left',LEFT_COLOR)} one step right to try replacing it with a <b>taller</b> line.
`);
left +=1;}else{notification(`
⬅️ ${makeColoredSpan('right',RIGHT_COLOR)} is the <b>shorter or equal</b> side
(<b>${makeColoredSpan(height[right],RIGHT_COLOR)}</b> vs <b>${makeColoredSpan(height[left],LEFT_COLOR)}</b>).<br/>
Being a <b>shorter or equal side</b> makes it a <b>bottleneck</b> for height, and width will never expand back (it only shrinks with each move).
Therefore, keeping it cannot yield a larger area.
👉 Move ${makeColoredSpan('right',RIGHT_COLOR)} one step left to try replacing it with a <b>taller</b> line.
`);
right -=1;}endBatch();}notification(`🏁 <b>Finished!</b> The maximum water container has an area of <b><code>${maxWater}</code></b>.`);return maxWater;}functionexplanationAndColorPaletteNotifications(){explanationNotification();notification(`
🎨 <b>Color Palette & Pointer Legend</b><br/>
• ${makeColoredSpan('left / height[left]',LEFT_COLOR)} — <i>left pointer</i> (index and value are shown in this color).<br/>
• ${makeColoredSpan('right / height[right]',RIGHT_COLOR)} — <i>right pointer</i> (index and value are shown in this color).<br/>
• <b>maxWater</b> — running maximum area (displayed as a separate variable).
`);}functioninitClassProperties(){setClassProperties(LEFT,{backgroundColor:LEFT_COLOR});setClassProperties(RIGHT,{backgroundColor:RIGHT_COLOR});}
Solution explanation
Solution explanation
Approach
Problem
Given a height array of length n (non-negative integers), pick two lines that,
together with the x-axis, form a container holding the maximum water, and
return the area of that container.
For indices i and j (0 ≤ i < j < n),
the area is (j − i) × min(height[i], height[j]).
Pointers & State
left — starts at 0, points to the left line.
right — starts at n − 1, points to the right line.
maxWater — running maximum area found so far.
Key Insight
Area = width × min(height[left], height[right]).
Moving either pointer always shrinks the width.
The shorter (or equal) side is a bottleneck for minimum height — keeping it cannot increase the minimum height,
and since the width does not expand back (it only shrinks at each move), it cannot yield a larger area.
👉 Therefore, always move the pointer on the shorter (or equal) side to try to replace it with a taller line.
Algorithm (Step-by-Step, matching the code)
Initialize
left = 0, right = n − 1.
maxWater = 0.
Whileleft < right:
Measure the current container width = right − left,
minHeight = min(height[left], height[right]),
area = width × minHeight.
UpdatemaxWater if area is larger.
Move the shorter side (symmetric reasoning):
If height[left] < height[right] → advance
left by one.
Else (the right side is shorter or equal) → retreat
right by one.
Rationale: the shorter (or equal) side is the bottleneck for height; width is shrinking anyway, so keeping the
shorter side cannot improve area. Moving it is the only chance to find a taller minimum height.
ReturnmaxWater after the loop terminates.
Correctness & Termination
Each step strictly shrinks the window by moving exactly one pointer; therefore the loop
while (left < right) must terminate in at most n − 1 iterations.
A larger area is only possible if the minimum height increases; since width shrinks, keeping the shorter side cannot help.
Always moving the shorter side systematically considers exactly those candidates that could raise the minimum height, ensuring the maximum is found.
Time Complexity
O(n)
We use a two-pointer scan across the array.
Each step moves exactly one pointer (left or right),
strictly shrinking the window.
Therefore, the loop runs for at most n − 1 iterations, giving overall O(n) time.
Space Complexity
O(1)
We only store a few variables:
left,
right, and
maxWater.
No extra data structures are used beyond the input array,
so the additional space usage is constant.
Input-1
Visucodize editorial solution titled JS Solution for LeetCode's Container with Most Water coding problem. Includes code and may include explanation. You can animate the code step by step using the provided input by clicking the run button, or fork it locally to update the code and input for custom visualization. View the original problem at https://leetcode.com/problems/container-with-most-water.