中等LeetCode 11可逐步演示引导学习
盛最多水的容器
双指针:从最大宽度开始夹逼
左右双指针从两端夹逼:每步算出当前容器的面积,然后移动"更矮的那根板"——因为面积只可能由矮板决定。
时间复杂度 O(n)空间复杂度 O(1)
所属套路:对撞双指针框架
题单:面试热题
题目描述
给定一个整数数组 height,第 i 个元素表示第 i 根竖板的高度。选出两根板,使它们与 x 轴围成的容器能装最多的水(面积 = 两板间距 × 两板中较矮的高度),返回最大面积。
学习目标
能解释面积由矮板决定,并证明每次移动矮板不会错过更优解,从而说清双指针为什么 O(n)。
已完成 0 / 6 阶段
诊断
先看面积由谁决定
两根板围成的面积怎么算?如果一边很高、一边很矮,面积由哪边决定?
height = [8, 1],两板间距 1,面积是多少?
建议先完成当前阶段(提示 / 检查 / 自评),再进入下一步;也可以直接跳过。
解题思路
核心思想
左右双指针从两端夹逼:每步算出当前容器的面积,然后移动"更矮的那根板"——因为面积只可能由矮板决定。
为什么需要它
暴力枚举所有两根板的组合是 O(n²)。而"高度由矮板决定"这个性质说明:很多组合根本不需要试——它们注定不会比当前更优。
第一反应:直觉方案
双重循环枚举所有 (i, j),算 min(height[i], height[j]) × (j - i) 取最大。直观,但慢。
关键洞察
关键洞察是证明"移动矮板是安全的":当前左右两根板中假设左边更矮。如果保留左边不动、只移动右边,宽度只会变小,而高度仍被左边的矮板卡住——面积不可能变大。也就是说,左边这根矮板搭档任何右边位置的板都不会更优,可以永久放弃。每一步都排除一根板、宽度减一,最多 n 步扫完——这就是"每次排除一个确定不会更优的候选",和二分查找的排除思想一脉相承。
时间复杂度 O(n)空间复杂度 O(1)
易错点
- 面积是 min(两根高度) × 宽度,别写成两根高度的乘积
- 先比较两根板的高度,再决定移动哪根——移动更高的那根可能错过最优解
- 两根一样高时移动任意一根都可以,不影响答案
逐步演示
参考代码
1function maxArea(height) {
2 let left = 0, right = height.length - 1;
3 let best = 0;
4 while (left < right) {
5 const h = Math.min(height[left], height[right]);
6 const w = right - left;
7 best = Math.max(best, h * w);
8 if (height[left] < height[right]) {
9 left += 1;
10 } else {
11 right -= 1;
12 }
13 }
14 return best;
15}
效果图
预测:答对 0 / 共 1 题
第 1 / 14 步