LeetCode #11 Container With Most Water

Problem

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.

Example

img

The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.

Note

You may not slant the container and n is at least 2.

Solution1

Method: Brute Force

Time Complexity: O(n ^2)

Space Complexity: O(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution:
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
res = float('-inf')
length = len(height)
for l_idx in range(length - 1):
for r_idx in range(l_idx, length):
h = min(height[l_idx], height[r_idx])
w = r_idx - l_idx
res = max(res, h*w)

return res

Solution2

Method: Greedy

Time Complexity: O(n)

Space Complexity: O(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution:
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
# / max{v(i, j), S(i...j-1)}; height(i) >= height(j)
# S(i..j) = |
# \ max{v(i, j), S(i+1...j)}; height(i) < height(j)
left = 0
right = len(height) - 1
res = float('-inf')

while left < right:
min_height = min(height[left], height[right])
res = max(res, min_height * (right - left))

while left <= right and height[left] <= min_height:
left += 1

while left <= right and height[right] <= min_height:
right -= 1

return res

Solution3

Method: Greedy

Time Complexity: O(n)

Space Complexity: O(1)

1
2
3
4
5
6
7
8
9
10
11
class Solution:
def maxArea(self, height):
i, j = 0, len(height) - 1
water = 0
while i < j:
water = max(water, (j - i) * min(height[i], height[j]))
if height[i] < height[j]:
i += 1
else:
j -= 1
return water