11.盛最多水的容器
给定一个长度为n
的整数数组height
。有n
条垂线,第i
条线的两个端点是(i, 0)
和(i, height[i])
。
找出其中的两条线,使得它们与x
轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明: 你不能倾斜容器。
示例 1:
输入:[1,8,6,2,5,4,8,3,7]
输出: 49
解释: 图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入: height = [1,1]
输出: 1
提示:
解法一(双指针)
思路分析:
- 首先确定最大盛水容量有关的两个因素, 即
x
轴尽可能宽,height
尽可能高; 且高受限于两边的最低高度; - 存在两边,所以考虑使用双指针, left指向左边, right指向右边; 即容量为
area = Math.min(height[left], height[right]) * (right - left)
- 可以从最大宽度开始变化,即left指向起始位置, right指向末尾位置, 然后尝试变化左右指针来获取最大盛水容量;
- 当左指针高度(height[left]) < 右指针高度时(height[right]), 若移动右指针,在宽度本身变小的情况,高度不发生变化, 则容量肯定变小, 移动右指针没有意义; 所以此时应该移动左指针
- 同理, 当 height[left] > height[right]时, 移动右指针right;
- 在变化过程中始终保持记录最大容量
area = Math.max(area, Math.min(height[left], height[right]) * (right - left))
;
实现代码如下:
java
class Solution {
public int maxArea(int[] height) {
// 最大水量
int area = 0;
int left = 0;
int right = height.length - 1;
while (left < right) {
area = Math.max(area, Math.min(height[left], height[right]) * (right-left));
if (height[left] > height[right]) {
-- right;
} else {
++ left;
}
}
return area;
}
}
提交结果如下:
解答成功: 执行耗时:4 ms,击败了67.68% 的Java用户 内存消耗:56.9 MB,击败了23.36% 的Java用户
复杂度分析:
- 时间复杂度:
, 遍历数组 - 空间复杂度: