1、题目描述
1.1 移动所有零至数组末尾
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
1.2 示例
示例 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
2、解题思路
2.1 思路讲解
- 注意:线是没有宽度的,此题不同于接雨水问题
- 两条线段的水量取决于较短的线
- 可以假设最外层的两个线段是最大值,然后逐层向里判断
- 考虑使用双指针
- 每次循环只移动左右指针中较小的一个,因为瓶颈在较小值,移动的目的是为了试图找到更优值。
- 移动指针时,如果下一个线段得值小于当前右指针的线段值,则忽略跳入下次循环。因为使用更短的线段会使情况更糟糕
- 依次循环至左右指针相遇,取最大值
2.2 动画演示( 待补充)
3、答案
3.1 Java 代码
public class _05_盛水最多容器 {
public static void main(String[] args) {
System.out.println(maxArea(new int[]{1, 8, 6, 2, 5, 4, 8, 3, 7}));
System.out.println(maxArea(new int[]{1, 1}));
}
public static int maxArea(int[] height) {
if (height == null || height.length < 2) {
return 0;
}
int L = 0, R = height.length - 1;
int water = (R - L) * (Math.min(height[L], height[R]));
while (L < R) {
if (height[L] <= height[R]) {
L++;
} else {
R--;
}
water = Math.max(water, (R - L) * Math.min(height[L], height[R]));
}
return water;
}
}