LeetCode-双指针-盛最多水的容器
LeetCode-双指针-盛最多水的容器
✏️ 关于专栏:专栏用于记录
prepare for the coding test
。
文章目录
- LeetCode-双指针-盛最多水的容器
- 📝 盛最多水的容器
- 🎯题目描述
- 🔍 输入输出示例
- 🧩题目提示
- 🧪枚举法
- 🧪双指针
- 💡思路
- ⏱️ 复杂度分析
- 🌟 总结与易错点
- ✅ 核心知识点
- 双指针思想(Two Pointers)
- 贪心思想的局部决策
📝 盛最多水的容器
🎯题目描述
给定一个长度为
n
的整数数组height
。有n
条垂线,第i
条线的两个端点是(i, 0)
和(i, height[i])
。找出其中的两条线,使得它们与x
轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。**说明:**你不能倾斜容器。
🔗题目链接:盛最多水的容器
🔍 输入输出示例
示例 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
🧩题目提示
n == height.length
2 <= n <= 105
0 <= height[i] <= 104
🧪枚举法
暴力枚举法
既然要求两条线构成的最大容积,那就计算这些线两两构成的容积大小,以得到最大的容积。这个方法只需要两层for循环即可。但这个算法的时间复杂度过高,最终会导致超时。
class Solution {
public:int maxArea(vector<int>& height) {int maxCap = 0;for(int i = 0; i < height.size(); i++){for(int j = i + 1; j < height.size(); j++){int capacity = min(height[i], height[j]) * (j - i);maxCap = max(maxCap, capacity);}}return maxCap;}
};
🧪双指针
💡思路
我们需要找出两条线段,使得它们之间形成的容器能够容纳最多的水。容积的计算公式为:
容积 = (右指针 - 左指针) × min(height[左], height[右])
暴力法 是枚举所有组合,时间复杂度为 O(n²),不可接受。
优化策略:使用双指针,即:
- 初始化两个指针
left
和right
,分别指向数组的两端。 - 计算当前容器的面积
area = (right - left) * min(height[left], height[right])
。 - 为了找到更大的面积,移动较短的那一边的指针,因为这是面积增大的唯一可能。
- 注意:当左右两边高度相等时候,需左右指针同时移动。
- 每次移动后重新计算面积并更新最大值。
- 直到
left >= right
,结束循环。



class Solution {
public:int maxArea(vector<int>& height) {int left = 0, right = height.size() - 1;int max_area = 0;while (left < right) {int h = min(height[left], height[right]);int w = right - left;max_area = max(max_area, h * w);// 关键:移动较短的那一边if (height[left] < height[right]) left++;else if (height[left] > height[right]) right--;else { // 两边高度相等时,双指针同时移动left++;right--;}}return max_area;}
};
⏱️ 复杂度分析
项目 | 复杂度 |
---|---|
时间复杂度 | O(n) |
空间复杂度 | O(1) 原地操作 |
🌟 总结与易错点
✅ 核心知识点
双指针思想(Two Pointers)
-
双指针是一种常见的线性扫描技巧,适用于在有序结构上进行区间收缩、滑动窗口等操作。
-
本题用双指针分别从数组两端向中间推进,避免了穷举所有组合(暴力 O(n²))的低效。
-
非零元素交换顺序错乱;
-
不清楚原地操作的含义,使用辅助数组(违反题意);
-
忘记处理全为 0 或全为非 0 的边界情况。
贪心思想的局部决策
-
每次比较
height[left]
和height[right]
,只移动较小的那一边,因为移动较大的一边不会让面积变大。 -
这个决策是贪心的 —— 每次尝试“可能变大的方向”,排除不可能提升面积的选择。
-
每次比较
height[left]
和height[right]
,只移动较小的那一边,因为移动较大的一边不会让面积变大。 -
这个决策是贪心的 —— 每次尝试“可能变大的方向”,排除不可能提升面积的选择。
❌ 易错点修正
❌ 忽略两边相等时应双指针同时移动,导致错过最大面积
❌ 忘记更新最大值(只更新指针,不更新 area)
❌ 使用暴力法,时间复杂度过高