11. Container With 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.
Example:
Input: [1,8,6,2,5,4,8,3,7]
Output: 49
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Think and method:
For the purpose, we need to find two lines in the coordinates represented by the array to maximize the volume (or more figuratively area) that they constitute with the X-axis.
I. Law of Violence (improperly conceived)
And, of course, we could do it with violence, because this is essentially a double traversal problem, and we can certainly do it with two for’s, going from one side, and calculating the area between them.
But after a period of practice, we need a better approach to performance, rather than simply sacrificing the time cost for a result.
Ⅱ. double pointer
Let’s consider the problem again. The two Pointers start out pointing to the values on both sides. In fact, the volume (area) is obtained by multiplying the smaller value of the data the two Pointers point to and the distance between the Pointers.Since there are two variables, after consideration, we find that moving the small pointer is the only solution, so that the height can be increased while the distance is decreased, and the effect of capacity increase can be achieved.Moving a large pointer does not do this.
Let’s consider an example
{1,3,8,2,7}
- We first move the left pointer to the right, at this time the capacity is 3*3 = 9, at this time the left pointer 3 is still smaller than the right pointer 7, move the left pointer.
- At this time, the capacity is 7*2 = 14, and the left pointer 8 is still greater than the right pointer 7, so move the right pointer.
- At this time, the capacity is 8*1 = 8. Since the two are already adjacent, there is no need to move any more
- If we update the maximum value at each step in the above process, we can get the desired result 14 after the traversal is completed once
From this, we can implement it
Time complexity: O(n) only one traversal
Space complexity: O(1)
Code:
func maxArea(height []int) int {
result := 0
left, right := 0, len(height) - 1
for left < right {
volume := 0
//calculate the present volume
volume = (right - left) * min(height[left],height[right])
//consider left and right
if height[left] < height[right] {
left++
} else {
right--
}
//every time refresh the result
if result < volume {
result = volume
}
}
return result
}
func min(a, b int) int {
if a <= b {
return a
}
return b
}
Test:
Example1:
Input: [1,8,6,2,5,4,8,3,7]
Example2:
Input: [1,3,8,2,7]