Start learning free

LESSON 251 OF 409 · TWO POINTERS

Container with Most Water - C++ Solution and Time Complexity Analysis /homework

Practice O(n) Read the full explanation

You are given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i are (i, ai) and (i, 0). Find two lines, which together with the x-axis form a container, such that this container contains the most water.

Note: You may not slant the container and n is at least 2.

 

The above vertical lines are represented by the array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) one container can contain is 49.

 

Example:

Input: [1,8,6,2,5,4,8,3,7]
Output: 49
STEP 1 OF 7
    Ctrl + Enter to check

    C++ · TWO POINTERS

    Container With Most Water in C++, explained

    Understanding the Problem

    The core challenge of this problem is to find two lines that, together with the x-axis, form a container that holds the maximum amount of water. This problem is significant in various fields such as computer graphics, game development, and any scenario where spatial optimization is required.

    Potential pitfalls include misunderstanding the constraints (e.g., assuming the lines can be slanted) and not considering all possible pairs of lines.

    Approach

    To solve this problem, we can start with a naive approach and then move to more optimized solutions.

    Naive Solution

    The naive solution involves checking all possible pairs of lines and calculating the area for each pair. This approach is not optimal due to its high time complexity of O(n^2).

    Optimized Solution

    A more efficient approach uses the two-pointer technique. We start with two pointers, one at the beginning and one at the end of the array, and move them towards each other. At each step, we calculate the area formed by the lines at the two pointers and update the maximum area if the current area is larger. We then move the pointer pointing to the shorter line inward, as this might help in finding a taller line that could potentially form a larger area.

    Algorithm

    Here is a step-by-step breakdown of the optimized algorithm:

    1. Initialize two pointers, one at the beginning (left) and one at the end (right) of the array.
    2. Initialize a variable to keep track of the maximum area found.
    3. While the left pointer is less than the right pointer:
      • Calculate the area formed by the lines at the left and right pointers.
      • Update the maximum area if the current area is larger.
      • Move the pointer pointing to the shorter line inward.
    4. Return the maximum area found.

    Code Implementation

    #include <vector>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    // Function to find the maximum area of water that can be contained
    int maxArea(vector<int>& height) {
        int left = 0; // Initialize left pointer
        int right = height.size() - 1; // Initialize right pointer
        int max_area = 0; // Initialize max area
    
        // Loop until the two pointers meet
        while (left < right) {
            // Calculate the area with the current left and right pointers
            int width = right - left;
            int current_height = min(height[left], height[right]);
            int current_area = width * current_height;
    
            // Update max area if the current area is larger
            max_area = max(max_area, current_area);
    
            // Move the pointer pointing to the shorter line inward
            if (height[left] < height[right]) {
                left++;
            } else {
                right--;
            }
        }
    
        return max_area; // Return the maximum area found
    }
    
    // Main function to test the maxArea function
    int main() {
        vector<int> height = {1, 8, 6, 2, 5, 4, 8, 3, 7};
        cout << "The maximum area of water the container can contain is: " << maxArea(height) << endl;
        return 0;
    }
    

    Complexity Analysis

    The time complexity of the optimized solution is O(n) because we only traverse the array once with the two pointers. The space complexity is O(1) as we are using a constant amount of extra space.

    Edge Cases

    Potential edge cases include:

    • Arrays with only two elements, which is the minimum valid input size.
    • Arrays where all elements are the same height.
    • Arrays with very large or very small values.
    Each of these cases is handled by the algorithm as it does not make any assumptions about the values other than the constraints provided.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Simple cases with small arrays.
    • Cases with large arrays to test performance.
    • Edge cases as mentioned above.
    You can use testing frameworks like Google Test for C++ to automate and manage your test cases.

    Thinking and Problem-Solving Tips

    When approaching such problems:

    • Understand the problem constraints and requirements thoroughly.
    • Start with a brute-force solution to understand the problem better.
    • Look for patterns and optimizations to improve your solution.
    • Practice similar problems to improve your problem-solving skills.

    Conclusion

    In this blog post, we discussed the "Container with Most Water" problem, explored a naive and an optimized solution, and provided a detailed explanation of the algorithm and its implementation in C++. Understanding and solving such problems is crucial for improving your algorithmic thinking and coding skills.

    Additional Resources

    For further reading and practice, consider the following resources:

    Keep going with C++About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free