Sweaty Imposter

Container With Most Water

MediumTwo PointersBlind 75MidOpen on LeetCodeUpdated

You're given an array height where height[i] is the height of a vertical line standing at x = i. Pick two lines; together with the x-axis they form a container. It holds water equal to the distance between the two lines times the shorter line's height, and any lines in between are ignored. Return the largest amount of water a container can hold. The container can't be tilted.

Examples

height = [1,8,6,2,5,4,8,3,7] returns 49

186254837
Lines 1 and 8 hold water 7 high across a width of 7.

The lines at index 1 (height 8) and index 8 (height 7) are 7 apart, and the water can only rise to the shorter one, 7, so they hold 7 * 7 = 49. The two 8s at indices 1 and 6 only give 8 * 5 = 40.

height = [1,1] returns 1

The only pair is 1 apart with height 1, so it holds 1 * 1 = 1.

Constraints

  • 2 <= height.length <= 10^5
  • 0 <= height[i] <= 10^4

Hints

Hint 1

Area is bounded by the shorter side and the width: which side limits you, and which should you discard?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

Start with the widest pair, the two ends. The water is capped by the shorter line, and pairing that line with anything closer only loses width without raising the cap, so it can be discarded: move the shorter side inward. Track the best area at every step until the two indices meet. On equal heights, moving either side is safe.

Time

O(n)

Space

O(1)

Pitfall

Always move the shorter line inward. Moving the taller one can never help, since the height stays capped by the shorter line while the width shrinks. Unlike Trapping Rain Water, the lines between the chosen pair don't matter.

Solutions

class Solution {
    public int maxArea(int[] height) {
        int left = 0, right = height.length - 1, best = 0;
        while (left < right) {
            int h = Math.min(height[left], height[right]);
            best = Math.max(best, h * (right - left));
            if (height[left] < height[right]) left++;
            else right--;
        }
        return best;
    }
}
Drill This