热题100 - 5. 盛最多水的容器(Java 题解)
LeetCode 热题100 - 5. 盛最多水的容器(Java 题解)
题目链接
难度
中等
题目描述
给定一个长度为 n 的整数数组 height。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。
说明:不能倾斜容器。
解题思路
本题最优解法为对撞双指针,时间复杂度 O (n),空间复杂度 O (1)。
核心思路:
- 容器面积 = 两板间距 × 两板中较矮的高度;
- 初始用左右指针分别指向数组两端,宽度最大;
- 每次移动较矮的一侧指针:
- 因为面积由短板决定,移动短板才有可能让面积变大;
- 移动高板只会让宽度变小,面积一定更小;
- 遍历过程中不断更新最大面积,直到两指针相遇。
复杂度分析
-
时间复杂度:O(n)
左右指针只遍历一次数组。
-
空间复杂度:O(1)
仅使用常数额外空间。
解题代码(Java)
class Solution {
public int maxArea(int[] height) {
int length = height.length;
int left = 0, right = length - 1;
int result = 0;
while (left < right) {
int l = height[left];
int r = height[right];
// 计算当前容器面积
int cup = Math.min(l, r) * (right - left);
// 更新最大面积
result = Math.max(result, cup);
// 移动较矮的一侧指针
if (l < r) {
left++;
} else {
right--;
}
}
return result;
}
}
代码解释
-
左右指针初始化
left从左端开始,right从右端开始,保证初始宽度最大。 -
面积计算
面积由较矮的板决定高度,两指针间距为宽度。
-
指针移动规则(核心)
哪边矮移动哪边,试图找到更高的板来增大面积。
-
全局最大值更新
每次计算面积后与当前最大值比较,保留更大值。
示例
输入:height = [1,8,6,2,5,4,8,3,7]
输出:49
过程简述:
- 左右指针从两端开始逐步向中间收缩;
- 最终在
8和7处取得最大面积。
易错点
- 面积一定是取 min (左,右),不能直接相乘;
- 必须移动较矮一侧指针,否则无法得到最优解;
- 不要用暴力双重循环,时间复杂度 O (n²) 会超时;
- 循环条件是
left < right,不能带等号。
总结
本题是对撞双指针的经典例题,核心在于理解 “短板决定面积” 的贪心思想。
代码简洁高效,是面试高频必刷题。
浙公网安备 33010602011771号