【LeetCode】Detailed explanation of the container with the most water 11. Container With Most Water Given n non-negative integers a1, a2, ..., an


foreword

Continue to brush the questions, brush the questions for a while, and keep brushing the questions all the time.


text

What I bring to you today is a problem of finding the maximum volume

Original title:

Link: The container that holds the most water

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 is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
insert image description here
Example:
Input: [1,8,6,2,5,4,8,3,7]
Output: 49

Given
an integer array, the element of the array is the height of the container, such as the array [4, 5], which means that the left height of the container is 4, the right height is 5, and its maximum water capacity is 4 * 1 = 4, that is, the width is 1 and high is 4. This is because it is not the maximum height, but the minimum height (short board effect), to find the maximum water capacity of the container.

Idea 1:

The first thing that comes to mind is to violently traverse the height of the container. We can use a two-layer loop to violently enumerate the possible water holding capacity of all containers, and finally take out the maximum water holding capacity.

code

public int maxArea(int[] height) {
    
    
    if (height == null || height.length < 2) {
    
    
        return 0;
    }
    int maxArea = 0;
    for (int left = 0; left < height.length; left++) {
    
    
        for (int right = left + 1; right < height.length; right++) {
    
    
            int currentArea = Math.min(height[left], height[right]) * (right - left);
            if (maxArea < currentArea) {
    
    
                maxArea = currentArea;
            }
        }
    }
    return maxArea;
}

In the code explanation
code, use the left variable to point to the left side of the container, right to point to the right side of the container, the initial value of left is 0, which points to the leftmost height of the container, and the initial value of right is the next height of left, which is left + 1. Height;
currentArea is the current amount of water in the small container. Math.min(height[left], height[right]) is used to indicate the height of the container (ie, short board), and (right - left) is used to indicate the width of the container and the amount of water . = Container Shortboard Height * Container Width .

As shown in the figure above, the current water volume is 1, and the right is moved to the right, that is, right++, the
insert image description here
water volume at this time = 1 * 2, and the right moves down to traverse all the water volumes. If the current container's water volume is greater than maxArea, the Change the value of maxArea.
From the code, it can be concluded that the time complexity is O(N²) , and the submission result will not time out, but it is quite slow.
insert image description here

Idea 2:

Since there are a lot of invalid judgments in Idea 1, the search speed is relatively slow, so from the perspective of reducing invalid judgments, we can fix the left at the starting point and the right at the end point . At the beginning, the maximum water capacity of the container is the entire array. Length * min (starting point height, ending point height), as shown in the following figure:
insert image description here
After calculating the first water volume, which direction do we need to move? Readers are advised to think about it first.
Yes, we need to move the left, because the amount of water depends on the height of the short board. If we want to obtain the maximum water capacity, we need to increase the height of the short board . At this time, the left is smaller than the right, and the left needs to be increased, that is, left++.
We get the maximum water volume by constantly changing the directions of left and right.

code

public int maxArea(int[] height) {
    
    
    if (height == null || height.length < 2) {
    
    
        return 0;
    }
    int maxArea = 0;
    int left = 0;                  //初始left的指向
    int right = height.length - 1; //初始right的指向
    while (left < right) {
    
    
        int currentArea = Math.min(height[left], height[right]) * (right - left);
        if (maxArea < currentArea) {
    
    
            maxArea = currentArea;
        }
        if (height[left] <= height[right]) {
    
      //改变短板高度
            left++;
        } else {
    
    
            right--;
        }
    }
    return maxArea;
}

The code explains
that the initial value of left is 0, that is, it points to the far left of the container, and the initial value of right is the length of the array minus 1, that is, it points to the far right of the container.
In the while loop, as long as left < right, that is, when left and right do not meet, the current water volume is calculated and compared with maxArea. The following code block is used to change the height of the short board:

if (height[left] <= height[right]) {
    
      //改变短板高度
    left++;
} else {
    
    
    right--;
}

If the height of the left side of the container is less than or equal to the height of the right side of the container, the left pointer left++ will point to the next height. Similarly, if the height of the right side of the container is less than the height of the left side of the container, the right short board will be changed, that is, right–. Let's go, the initial state is as follows: the
insert image description here
height of the left side is smaller than that of the right side, so next time you need to change the short board on the left, that is, left++ . , at this time, move the right small to the right, change the short board on the right, right–, after the move, as shown in the following figure: Repeat the above steps until the left meets the right as shown in the above figure. Since the left meets the right, the left is smaller than the right at this time. left++, left is equal to right, does not meet the condition of while(left < right), the loop ends, returns the maximum result, submits the code Success , the speed is still significantly improved, comfortable!
insert image description here

insert image description here

insert image description here
insert image description here
insert image description here
insert image description here
insert image description here

insert image description here


Summarize

If you have read my last blog, you will find that the idea 3 of the previous question is somewhat similar to the idea 2 of this question. They both use the left and right pointers to sandwich them to find the results that meet the conditions.
Previous blog: [LeetCode] Detailed explanation of the sum of three numbers
In fact, this is a double-pointer type problem, and the ideas are similar. There are also special classifications in LeetCode, and interested students can check it out by themselves.
LeetCode double pointer problem
Well, today's topic explanation is here, if you have any doubts, you can put it in the message below, come on!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325982606&siteId=291194637