leetcode_11. Container With Most Water

Keywords: Go

leetcode_11. Container With Most Water

 

First, the question is:

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.

Translation:

Given n n n nonnegative integers a1, a2,..., an, each represents a point at coordinates (i, ai). Draw n vertical lines so that the two endpoints of line I are at (i, ai) and (i, 0). Find two lines that together with the x-axis form a container so that it contains the most water.

Note: You must not tilt the container (i.e. the board effect) and n should be at least 2.

 

 

Second, train of thought:

1. Violence law: find out the result directly through double cycle traversal.

2. Contour method: In fact, it is still for the copy of the method to find the N2 contour corresponding to n1, so as to find the corresponding maximum n2.

 

 

Third, code:

1.V1:

func maxArea(height []int) int {
    maxarea:=0
    for k:=0;k<len(height)-1;k++{
        for k2:=k+1;k2<len(height);k2++{
            minheight:=height[k]
            if height[k2]<height[k]{
                minheight=height[k2]
            }
            smaxarea:=(k2-k)*int(minheight)

            if smaxarea>maxarea{
                maxarea=smaxarea
            }
        }
    }
    return maxarea
}

Runtime:648ms,15.04%

Based on my previous experience, I'll start my second traversal on the right. Because it's more likely to produce bigger results.

And extract some internal methods.

The most important thing is that after the method is extracted, I can save a certain amount of memory (such as smaxarea).

 

2.V2:

func maxArea(height []int) int {
    maxarea:=0
    for k:=0;k<len(height)-1;k++{
        for k2:=len(height)-1;k2>k;k2--{
            maxarea=max(maxarea,(k2-k)*min(height[k],height[k2]))
        }
    }
    return maxarea
}

func min(a,b int) int {
    if a<b{
        return a
    }else{
        return b
    }
}

func max(a,b int) int {
    if a>b{
        return a
    }else{
        return b
    }
}

Runtime:592 ms,23.31%

Although it has improved, there is still a big gap. So there must be a huge performance improvement point.

After thinking, I think of a feature that when I find the height in the second cycle is higher than that in the first cycle, the result of this calculation must be the biggest result in the second cycle, and I can break it. In this way, I will save a lot of time.

The reason is that the height of my bucket rectangle is the highest in the first cycle (take the minimum), and the width must be gradually reduced. (I traversed from both sides to the middle)

 

3.V3:

func maxArea(height []int) int {
    maxarea:=0
    for k:=0;k<len(height)-1;k++{
        for k2:=len(height)-1;k2>k;k2--{
            
            if height[k]<height[k2]{
                maxarea=max(maxarea,(k2-k)*height[k])
                break
            }else{
                maxarea=max(maxarea,(k2-k)*height[k2])
            }
        }
    }
    return maxarea
}

func max(a,b int) int {
    if a>b{
        return a
    }else{
        return b
    }
}

Runtime:112 ms,33.83%

Perhaps not much, but the actual running time has increased by five times. This is a leap forward.

For code readability and minor modifications, let me just sort out the code.

 

4.V4:

func maxArea(height []int) int {
    maxarea:=0
    for left:=0;left<len(height)-1;left++{
        for right:=len(height)-1;right>left;right--{

            if height[left]<height[right]{
                maxarea=max(maxarea,(right-left)*height[left])
                break
            }else{
                maxarea=max(maxarea,(right-left)*height[right])
            }
        }
    }
    return maxarea
}

func max(a,b int) int {
    if a>b{
        return a
    }else{
        return b
    }
}

Runtime: 104 ms,33.83%

Small promotion, the key is to look comfortable.

 

 

Fourth, other people's code:

1. Best code:

func min(a, b int) int {
    if a < b {
        return a
    }else{
        return b
    }
}

func max(a, b int) int {
    if a < b {
        return b
    }else{
        return a
    }
}

func maxArea(height []int) int{
    area, left, right := 0, 0, len(height)-1
    for left < right {
        h := min(height[left], height[right])
        area = max(area, h*(right-left))
        for ; left < right && height[left] <= h; left++{
        }
        for ; left < right && height[right] <= h; right--{
        }
    }
    return area
}

Runtime:16ms,100%

 

2. analysis:

In fact, there are two wonderful points.

The first is the cyclic judgement condition left < right. The beauty of this condition is that it's in the previous code

 if height[left]<height[right]{
                maxarea=max(maxarea,(right-left)*height[left])
                break
            }else{
                maxarea=max(maxarea,(right-left)*height[right])
            }

Good cooperation. It saves time in two ways. Unfortunately, I only noticed its value in the second cycle. It is not linked to the first cycle. After understanding this, I refined my code:

V5:

func maxArea(height []int) int {
    length:=len(height)
    left,right,maxarea:=0,length-1,0
    for ;left<right;left++{
        for {

            if height[left]<=height[right]{
                maxarea=max(maxarea,(right-left)*height[left])
                break
            }else{
                maxarea=max(maxarea,(right-left)*height[right])
            }
            right--
        }
    }
    return maxarea
}

func max(a,b int) int {
    if a>b{
        return a
    }else{
        return b
    }
}

Runtime: 20 ms,82.71%

The combination of these two statements saves time from both internal and external loops. It needs a good understanding.

 

Due to the busy recent days, some blogs are almost busy, but there is no time to decorate them. It is estimated that the blog will be rougher after that.)

Posted by zardiw on Fri, 21 Dec 2018 21:06:05 -0800