LeetCode11, the container with the most water

1. Direct thinking method

class Solution {
    
    
    public int maxArea(int[] height) {
    
    
        if(height==null||height.length==0||height.length==1){
    
    
            return 0;
        }
        int max=0;
       for(int j=0;j<height.length;j++)//起点
        {
    
    
            for(int i=1;i<=height.length-1;i++){
    
    //控制底边的长度。
            
                if(j+i<height.length){
    
    
                    int water = Math.min(height[j],height[j+i])*i;
                    if(max<water)
                        max = water;
                }else
                break;
            }

        }

    return max;
}
}

Accept once, but the efficiency is touching:

Insert picture description here
There is no doubt that the time complexity has reached O(N 2 )

2. Dynamic programming method

According to Tsinghua, the dynamic planning steps are:

  • 1. Determine the status

The key to determining the state is to
find the last step, and then from the last step to derive the structure of the sub-problem.

In this question, the final result is that we have found the two endpoints that make the most of the water: ai, aj, and res. So what was her last step? The last step must be looking for these two endpoints or one of the endpoints, that is to say: In other words, there will be a subscript movement. So there is a sub-problem. 我们找当前的ai,aj,需要找到上一次的某两个端点a1,a2,她的盛水量不是最大的。(如何知道不是最大的,我们需要一个记录量,记录当前的最大量,即res)才会出现下标的移动。The results are as follows:

    • (a[i],a[j])<-(a[i-1],a[j]),if(a[i-1]<a[j])
    • (a[i],a[j])<-(a[i],a[j+1]),if(a[i]>a[j+1])

So we can deduce that when a[i][j] is calculated, the current maximum value we calculate is res. Next, we cannot determine whether res is the global maximum because we have not yet finished calculating the possible results. We have to calculate the values ​​of other endpoints. So we need to move the subscript, that is how to move it? When height[i]<height[j], the moving subscript should be i, whoever moves smaller, because:

Because the amount of water contained is determined by the
smaller of the numbers pointed to by the two pointers * the distance between the pointers
. If we move the pointer with the larger number, the former "the smaller value of the numbers pointed to by the two pointers" will not increase, and the latter "the distance between the pointers" will decrease, so this product will decrease. Then it doesn't meet our demand for finding the largest amount. Therefore, it is unreasonable for us to move the pointer with the larger number. Therefore, we move the pointer with the smaller number.

So define the state, open the array representation. Specifically, the dimension and size of the opened array must also be considered.

  • 2. Recursive equation
    res = min(res,(ji)*min(height[i],height[j]));
  • 3. Initial conditions and boundary conditions The
    initial conditions are that we have this possibility, but they cannot be calculated, and at the same time they need to be used for recursion.
    This question has no boundaries. Initial conditions: Two endpoints are required to hold water. So height.length<=1, return -1;
  • 4. The calculation sequence, that is, when the value is used, its need has been introduced. Nothing to consider here

Insert picture description here
Only after doing the above four steps can you start writing code.

class Solution {
    
    
    public int maxArea(int[] height) {
    
    
      if(height.length<=1)
        return -1;
        int i = 0,j=height.length-1,res = 0;
        while(i<j){
    
    
            int min = Math.min(height[i],height[j]);
            res = Math.max(res,(j-i)*min);
            if(height[i]<height[j]){
    
    
                i++;
            }else j--;
        }
        return res;
    }
}

Refer to the official solution (dual pointer method). This is the first time I really feel that I have touched the door of dynamic programming.

Guess you like

Origin blog.csdn.net/qq_44861675/article/details/108367541