力扣11. 盛最多水的容器
·
一、问题回顾
在力扣 11. 盛最多水的容器 中,我们面临这样的问题:给定 n 个非负整数 a₁,a₂,...,aₙ,每个数对应坐标平面上的一个点 (i, aᵢ)(此处 i 从 1 开始计数)。每条垂直线 i 的两个端点分别是 (i, 0) 和 (i, aᵢ),要求找出其中两条垂直线,使其与 x 轴共同构成的容器能容纳最多的水。
关键说明:
- 容器不可倾斜,水量高度由两条线中较矮的那条决定(超过该高度会溢出);
- 输入数组长度
n ≥ 2,确保至少存在两条垂直线可构成容器; - 核心计算公式:容器容量 = 两条线的水平距离 × 两条线的最小高度。
二、解题思路
本题的核心目标是找到 “水平距离尽可能远” 且 “较矮边尽可能高” 的两条线,以此最大化容器容量。我们先分析两种解题思路,突出最优方案的优势:
双指针法(最优解)
为了优化效率,我们采用 双指针 + 贪心策略,将时间复杂度降至 O(n),核心思路如下:
- 初始化指针:左指针
i从 1 开始(对应数组最左侧的线),右指针j从数组长度开始(对应数组最右侧的线); - 计算当前容量:利用公式
(j - i) × min(height[i-1], height[j-1])计算当前两条线构成的容量(注意转换为数组的 0-based 索引取值); - 更新最大容量:若当前容量大于已记录的最大值,则更新最大值;
- 移动指针(贪心核心):移动较矮边的指针—— 因为移动较矮边,才有可能找到更高的边,从而增大后续容量;若移动较高边,不仅距离缩短,高度还不会增加,容量必然变小;
- 循环终止:当两指针相遇时,遍历结束,此时记录的最大值即为最终答案。
三、代码实现
class Solution {
public:
int maxArea(vector<int>& height) {
// 初始化双指针:i为左指针(1-based,对应数组索引i-1),j为右指针(1-based,对应数组索引j-1)
// max用于存储最大容量,初始化为0
int i = 1, j = height.size(), max = 0;
// 循环条件:左指针小于右指针(两指针未相遇,仍有搜索空间)
while (i < j) {
// 计算当前容器容量:
// (j - i)是两指针的水平距离(因i和j是1-based,差值即实际距离)
// min(height[i-1], height[j-1])取两条线中较矮的高度(决定水量上限)
int m = (j - i) * min(height[i - 1], height[j - 1]);
// 若当前容量大于已记录的最大值,更新最大值(用swap交换等价于max = m)
if (m > max) swap(max, m);
// 贪心移动指针:移动较矮的边,寻找更高的线以可能增大容量
// 若左线更高,移动右指针(j--);否则移动左指针(i++)
height[i - 1] > height[j - 1] ? j-- : i++;
}
// 返回最大容量
return max;
}
};
四、代码逐行解析
1. 变量初始化
int i=1,j=height.size(),max=0:i=1:左指针初始化为 1,对应数组最左侧的线(后续通过i-1转换为 0-based 索引);j=height.size():右指针初始化为数组长度,对应数组最右侧的线(后续通过j-1转换为 0-based 索引);max=0:用于存储最大容量,初始值为 0。
2. 双指针循环逻辑
while(i<j):当左指针小于右指针时,持续循环(两指针未相遇,仍有搜索空间);int m=(j-i)*min(height[i-1],height[j-1]):计算当前容量:j - i:两指针的水平距离(因指针是 1-based,差值直接等于实际距离);min(height[i-1], height[j-1]):取两条线的最小高度(避免水量溢出);m:当前两条线构成的容器容量。
3. 最大容量更新
if(m>max)swap(max,m):若当前容量m大于已记录的最大容量max,则通过swap函数交换两者的值,等价于max = m,实现最大值更新。
4. 指针移动规则
height[i-1]>height[j-1]?j--:i++:三元表达式实现贪心移动:- 若左指针对应的线更高(
height[i-1] > height[j-1]),则右指针j--(移动较矮的右指针); - 否则,左指针
i++(移动较矮的左指针)。
- 若左指针对应的线更高(
5. 返回结果
return max:循环结束后,返回记录的最大容量。
五、复杂度分析
- 时间复杂度:
O(n)。双指针从两端向中间移动,每个元素最多被访问一次,遍历次数与数组长度成正比,效率远超暴力法; - 空间复杂度:
O(1)。仅使用i、j、max、m四个额外变量,不依赖输入规模,空间开销极小。
六、总结
本题的关键在于理解双指针法的贪心策略:通过移动较矮边的指针,确保每次遍历都向 “可能获得更大容量” 的方向前进,既保证了效率,又能找到最优解。
更多推荐

所有评论(0)