给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
思路:
法一:暴力法
找出所有可能的组合中面积最大的,时间复杂度O(n^2),计算所有n(n−1)/2种高度组合的面积空间复杂。空间复杂度O(1)
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
maxs = 0
for i in range(len(height)):
for j in range(i+1,len(height)):
maxs = max(maxs,min(height[i],height[j])*(j-i))
return maxs
法二:双指针法
利用两个指针,一首一尾,在移动指针时,移动对应长度较小的指针,尽管造成了矩形宽度的减小,但却可能会有助于面积的增大。而如果移动大指针则可能不会对于面积增加有任何帮助。
时间复杂度:O(n),一次扫描;空间复杂度:O(1),使用恒定的空间。
class Solution(object):
def maxArea(self, height):
l = 0
r = len(height)-1
maxs = 0
while(l<r):
maxs = max(maxs,min(height[l],height[r])*(r-l))
if height[l]< height[r]:
l += 1
else:
r -= 1
return maxs
20221204版本
class Solution {
public int maxArea(int[] height) {
int res = 0, l = 0, r = height.length - 1;
while(l < r){
res = height[l] <= height[r] ?
Math.max(res, (r - l) * height[l++]):
Math.max(res, (r - l) * height[r--]);
// 展开版
// if (height[l] <= height[r]){
// res = Math.max(res, height[l] * (r - l));
// l ++;
// } else {
// res = Math.max(res, height[r] * (r - l));
// r --;
// }
}
return res;
}
}