31. Container With Most Water

βœ… GFG solution to the Container With Most Water problem: find maximum water area between two vertical lines using optimal two-pointer technique. πŸš€

The problem can be found at the following link: πŸ”— Question Link

🧩 Problem Description

Given an array arr[] of non-negative integers, where each element arr[i] represents the height of vertical lines, find the maximum amount of water that can be contained between any two lines, together with the x-axis.

Note: In the case of a single vertical line, it will not be able to hold water.

The water area is calculated as: Area = min(height[i], height[j]) Γ— (j - i) where i and j are indices of two lines.

πŸ“˜ Examples

Example 1

Input: arr[] = [1, 5, 4, 3]
Output: 6
Explanation: Lines at indices 1 and 3 with heights 5 and 3 are 2 distance apart. 
Base = 2, Height = min(5, 3) = 3. Total area = 3 Γ— 2 = 6.

Example 2

Input: arr[] = [3, 1, 2, 4, 5]
Output: 12
Explanation: Lines at indices 0 and 4 with heights 3 and 5 are 4 distance apart.
Base = 4, Height = min(3, 5) = 3. Total area = 3 Γ— 4 = 12.

Example 3

πŸ”’ Constraints

  • $1 \le \text{arr.size()} \le 10^5$

  • $0 \le \text{arr}[i] \le 10^4$

βœ… My Approach

The optimal approach uses the Two Pointers technique with a Greedy Strategy to efficiently find the maximum water area:

Two Pointers + Greedy Algorithm

  1. Initialize Pointers:

    • Use two pointers: left at start (0) and right at end (n-1).

    • Initialize maxArea to track the maximum water area found.

  2. Calculate Current Area:

    • For current pointers, calculate area = min(h[left], h[right]) Γ— (right - left).

    • Update maxArea if current area is larger.

  3. Greedy Pointer Movement:

    • Move the pointer with the smaller height inward.

    • Why? Moving the pointer with larger height would only decrease the width while keeping the limiting height same or smaller, never improving the area.

  4. Convergence:

    • Continue until left >= right.

    • The algorithm guarantees we won't miss the optimal solution due to the greedy property.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the size of the array. Each element is visited at most once as we use two pointers moving towards each other.

  • Expected Auxiliary Space Complexity: O(1), as we only use a constant amount of additional space for variables like pointers and maxArea.

πŸ§‘β€πŸ’» Code (C++)

⚑ View Alternative Approaches with Code and Analysis

πŸ“Š 2️⃣ Optimized Pointer Movement

πŸ’‘ Algorithm Steps:

  1. Use two pointers approach but optimize pointer movement logic.

  2. Pre-calculate area only when we might find a better solution.

  3. Skip unnecessary calculations by comparing heights first.

  4. Move the pointer with smaller height to potentially find larger area.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Single pass through array

  • Auxiliary Space: πŸ’Ύ O(1) - Only constant variables

βœ… Why This Approach?

  • Slightly more readable with explicit height selection

  • Avoids redundant min() calculations

  • Better for understanding the logic flow

πŸ“Š 3️⃣ Bit Manipulation Optimization

πŸ’‘ Algorithm Steps:

  1. Use bit operations for faster comparisons where possible.

  2. Combine multiple operations into single expressions.

  3. Utilize compiler optimizations through simpler arithmetic.

  4. Minimize function calls and temporary variables.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Linear time with optimized operations

  • Auxiliary Space: πŸ’Ύ O(1) - Minimal variable usage

βœ… Why This Approach?

  • Most compact and optimized code

  • Combines increment/decrement with ternary operator

  • Minimal memory footprint and operations

πŸ“Š 4️⃣ Early Termination Optimization

πŸ’‘ Algorithm Steps:

  1. Track the maximum possible area that can be achieved.

  2. If current width Γ— max_height cannot exceed current maxArea, terminate early.

  3. Use preprocessing to find maximum height for optimization.

  4. Skip iterations that cannot improve the result.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Linear with early termination potential

  • Auxiliary Space: πŸ’Ύ O(1) - Constant space

βœ… Why This Approach?

  • Potential for early termination in favorable cases

  • Maintains optimal complexity while adding optimization

  • Good for large datasets with specific patterns

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

🏷️ Standard Two Pointer

🟒 O(n)

🟒 O(1)

πŸš€ Optimal and clean

πŸ”§ Requires understanding greedy logic

πŸ” Optimized Movement

🟒 O(n)

🟒 O(1)

πŸ“– Better readability

πŸ’Ύ Slightly more operations

πŸ”„ Bit Manipulation

🟒 O(n)

🟒 O(1)

⭐ Most compact

πŸ”§ Less readable for beginners

⚑ Early Termination

🟒 O(n)

🟒 O(1)

🎯 Potential speedup

πŸ’Ύ Extra preprocessing overhead

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

πŸ… Production code, interviews

πŸ₯‡ Standard Two Pointer

β˜…β˜…β˜…β˜…β˜…

πŸ“– Learning purposes

πŸ₯ˆ Optimized Movement

β˜…β˜…β˜…β˜…β˜†

πŸ”§ Competitive programming

πŸ₯‰ Bit Manipulation

β˜…β˜…β˜…β˜…β˜…

🎯 Large datasets with patterns

πŸŽ–οΈ Early Termination

β˜…β˜…β˜…β˜…β˜†

β˜• Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated