The container with the most water is greedy + double pointer

describe

Given an array height with a length of n, each number represents the height of a point in the coordinate axis, and height[i] is the height of the i-th point, please select 2 containers with the height and the x-axis at most How much water to hold.


method

volume = shortest side * base

The left pointer left scans from the beginning of the array to the right, and the right pointer right scans from the end of the array to the left. 

At the initial moment, left points to the first element, right points to the tail element, volume=min(height[left],height[right])*(right-left).

At this time, there is a shorter side among the left and right sides. It may be assumed that height[left]<=height[right], that is, the left side is shorter.

There are two ways to go:

(1) Move the left pointer one step to the right

容积=min(height[left+1],height[right])*(right-left-1)

height[right] remains unchanged, height[left+1] may become larger or smaller, (right-left-1) becomes smaller, and the volume may become larger.

(2) The right pointer moves one step to the left

容积=min(height[left],height[right-1])*(right-1-left)

height[left] remains unchanged, and because height[left]<=height[right], the shortest side length min(height[left],height[right-1]) will not become larger, and the bottom side length (right-1 -left) becomes smaller and the volume becomes smaller.

Therefore, in order to find the maximum volume, the pointer on the shorter side should be moved (equivalent to pruning, knowing that there is no better solution in a certain part of the search space, so this part of the space will not be searched).

Search termination condition: left>=right, the variable res maintains the maximum volume.


C++ code

class Solution {
public:
    int maxArea(vector<int>& height) {
        //排除不能形成容器的情况
        if(height.size() < 2) 
            return 0;
        int res = 0; 
        //双指针左右界
        int left = 0; 
        int right = height.size() - 1;
        //共同遍历完所有的数组
        while(left < right){ 
            //计算区域水容量
            int capacity = min(height[left], height[right]) * (right - left);
            //维护最大值 
            res = max(res, capacity); 
            //优先舍弃较短的边
            if(height[left] < height[right]) 
                left++;
            else
                right--;
         }
        return res;
    }
};

Guess you like

Origin blog.csdn.net/Seattle_night/article/details/127409188