11. 盛最多水的容器

1. 题目

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0)(i, height[i])

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例 1:

img

1
2
3
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

1
2
输入:height = [1,1]
输出:1

提示:

  • n == height.length
  • 2 <= n <= 105
  • 0 <= height[i] <= 104

2. 思路

  • 根据题目提供的柱状图,希望得到的是最大的存水量,实际上就是求最大的面积,因此考虑使用双指针进行解决
  • 初始化左指针l和右指针r,同时计算初始结果变量maxArea,面积的计算为(r - l) * (l下标和r下标对应高度较小的值),取高度较高的值会导致”漏水”
  • height数组开启循环,当l < r时,持续循环进行计算最大的maxArea值,
  • 当下标l对应的高度小于下标r对应的高度时,l指针自增1
  • 当下标r对应的高度小于等于下标l对应的高度时,r指针自减1
  • 利用Math.max函数计算当前已得到的最大面积maxArea与移动后的lr下标对应的面积并赋值给maxArea变量

3. 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int maxArea(int[] height) {
var l = 0;
var r = height.length - 1;
var maxArea = (r - l) * Math.min(height[l], height[r]);

while (l < r) {
if (height[l] < height[r]) {
l++;
} else {
r--;
}

maxArea = Math.max(maxArea, (r - l) * Math.min(height[l], height[r]));
}

return maxArea;
}
}

4. 复杂度

  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

image-20230812020256415