整体思路
这段代码采用了双指针(Two-Pointers) 的优化算法来解决"盛最多水的容器"问题。与暴力枚举所有可能性的 O(n²) 方法不同,双指针法通过一种更智能的收缩策略,仅需一次遍历即可找到最大面积,效率极高。
其整体思路如下:
-
初始化指针 :算法设置两个指针,
left
指向数组的第一个元素(索引 0),right
指向数组的最后一个元素(索引n-1
)。这两个指针代表了当前考虑的容器的左右两个边界。这个初始状态构成了宽度最大的容器。 -
迭代收缩 :指针
left
和right
在一个while
循环中相向移动,直到它们相遇(left >= right
)。在每次循环中,执行以下操作:- 计算当前面积 :容器的宽度是
w = right - left
,高度h
则由两个边界中较短的那条线决定,即h = Math.min(height[left], height[right])
。当前容器的面积就是area = w * h
。 - 更新最大面积 :将当前计算出的
area
与全局最大面积ans
进行比较,并始终保留较大者。
- 计算当前面积 :容器的宽度是
-
指针移动策略(核心) :这是算法的关键所在。在计算完当前面积后,需要决定移动哪个指针(
left
还是right
)来寻找下一个可能的更大容器。- 当前面积受限于宽度 和高度 。由于指针在相向移动,宽度
w
在后续的迭代中只会减小,不会增大。 - 因此,要想找到一个更大的面积,唯一的希望就是增加容器的高度
h
。 - 容器的高度
h
由height[left]
和height[right]
中的短板决定。如果移动长板那一侧的指针,短板依然是那个短板,高度h
不会增加(甚至可能减小),而宽度w
又减小了,所以面积必然不会变大。 - 结论是:必须移动指向短板的那个指针。因为只有移动短板,才有可能在下一次迭代中遇到一个更高的板,从而增加容器的整体高度,弥补宽度减小的损失,进而才有可能找到更大的面积。
- 当前面积受限于宽度 和高度 。由于指针在相向移动,宽度
-
返回结果 :当
while
循环结束时(left
和right
相遇),意味着所有具有潜力的容器都已被考虑过。此时ans
中存储的就是最终的最大面积。
完整代码
java
class Solution {
public int maxArea(int[] height) {
// ans 用于存储并更新找到的最大面积,初始化为0。
int ans = 0;
// 初始化左指针,指向数组的起始位置。
int left = 0;
// 初始化右指针,指向数组的末尾位置。
int right = height.length - 1;
// 当左指针在右指针左侧时,持续循环。
// 这是双指针算法的核心循环结构。
while (left < right) {
// 计算当前容器的宽度,即两个指针之间的距离。
int w = right - left;
// 计算当前容器的高度,由左右两条线中较短的一条决定。
int h = Math.min(height[left], height[right]);
// 计算当前容器的面积。
int area = w * h;
// 将当前面积与已知的最大面积比较,并更新最大面积。
ans = Math.max(ans, area);
// --- 核心移动逻辑 ---
// 如果左边的线比右边的线短。
if (height[left] < height[right]) {
// 移动左指针向右。因为移动短板才有可能找到更高的板,从而可能获得更大的面积。
left++;
} else {
// 如果右边的线比左边的线短,或者两者一样高。
// 移动右指针向左。
right--;
}
}
// 循环结束后,ans 中保存的就是最终的最大面积。
return ans;
}
}
时空复杂度
时间复杂度:O(n)
- 分析依据 :算法使用
left
和right
两个指针。left
从0
开始向右移动,right
从n-1
开始向左移动。 - 在
while
循环的每一次迭代中,要么left
加一,要么right
减一,两个指针之间的距离right - left
至少会减少1。 - 两个指针只会相向移动,绝不会后退或停滞。它们从数组的两端开始,直到相遇为止。
- 因此,两个指针总共会移动
n-1
步。这意味着循环体内的操作最多执行n-1
次。
结论 :算法的执行时间与输入数组的规模 n
呈线性关系,因此时间复杂度为 O(n)。
空间复杂度:O(1)
- 分析依据 :算法在执行过程中,除了输入数组
height
本身占用的空间外,只使用了有限几个变量(ans
,left
,right
,w
,h
,area
)。 - 这些变量的数量是固定的,不随输入数组
height
的大小n
的增加而增加。 - 没有创建任何新的、大小与
n
相关的辅助数据结构(如额外的数组、哈希表等)。
结论 :算法所需的额外存储空间是常数级别的,因此空间复杂度为 O(1)。