Celenort
Conciencia
게시물 253
오늘 0
전체 0
A site about logging consciousness

[LeetCode] Container With Most Water

Container With Most Water

Category: Array

Deadline: 1st week (12/31 - 1/7)

Difficulty: Medium

Github: https://github.com/iamseokhyun/2022-algorithm-study/tree/master/array/ContainerWithMostWater/

LeetCode link: https://leetcode.com/problems/container-with-most-water/

Problem

You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]).

Find two lines that together with the x-axis form a container, such that the container contains the most water.

Return the maximum amount of water a container can store.

Notice that you may not slant the container.

Example 1:

Input: height = [1,8,6,2,5,4,8,3,7]

Output: 49

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

Example 2:

Input: height = [1,1]

Output: 1

Constraints:

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

Solution

public class Solution
{
    public int MaxArea(int[] height)
    {
        int l = 0;
        int r = height.Length - 1;
        int max = 0;
        int h;

        while (r > l)
        {
            h = (height[r] > height[l]) ? height[l] : height[r];
            max = (max > (h * (r - l))) ? max : (h * (r - l));

            if (height[r] > height[l])
            {
                l++;
            }
            else
            {
                r--;
            }
        }

        return max;
    }
}

Comment

  • 3Sum 문제와 동일하게 좌측과 우측에서 접근하는 pointer를 이용하면 편하다. 솔직히 이해하는데 좀 오래 걸렸는데, Greedy Algorithm이라고 한다.
  • 먼저 left = 0, right = h.Length - 1로 초기화해준다.
  • 담을 수 있는 물의 면적(2차원이니까 면적이 맞지!)은 h[l], h[r] 중 최솟값 곱하기 r-l이다. 이를 계산해서 max에 먼저 넣는다.
  • 우리는 r이나 l을 한칸씩 중심으로 옮기면서 최댓값을 찾을 것이다.
  • h[r]과 h[l] 의 대소관계가 결정될텐데, h[r]이 h[l]보다 크다고 생각해보자. 즉 오른쪽 벽이 더 높은 상황이다. 그렇다면 왼쪽 벽을 고정하고 오른쪽 벽만을 좌측으로 움직일 때 현재의 max값보다 더 많이 담을 수 있을까? 애초에 왼쪽벽이 더 높이가 작았으므로 오른쪽 벽이 더 높아진다 하더라도 왼쪽 벽에 의해 높이가 계속 결정되며, r-l은 당연히 작아지므로 최댓값은 달라지지 않는다. (가로x세로에서 세로는 일정, 가로가 줄어듦)하물며 왼쪽 벽보다 오른쪽 벽이 낮아지면 결과는 당연히 작아진다. (가로 x 세로에서 둘다 줄어드니까). 그렇다면 왼쪽 벽을 고정한 상황에서 모든 경우에 대한 최댓값은 처음 상황이다. 즉 l을 한칸 우측으로 밀어서 동일한 4를 반복한다.
  • 당연하지만 h[l]이 h[r]보다 크다면 4에서 좌/우만 바꾸어 생각하여 동일하게 우측벽을 고정하였을 때의 면적의 최댓값이 현재상태이며, 또다른 탐색을 위해서는 우측벽을 한칸 왼쪽으로 이동해야한다는 결론에 다다른다.
  • 이렇게 하여 l > r이 되면 탐색이 끝난다. 계속 갱신하던 max값을 그대로 출력한 것이 답이다.
댓글을 불러오는 중입니다.