文章目录
一、题目描述
给定一个长度为 n 的整数数组 height,数组中的每个元素代表一条竖立在坐标轴上的线段的高度。
目标是找到两条线,使得它们与 x 轴一起构成的容器能够装最多的水。
返回最大容积的值。
示例输入:
height = [1,8,6,2,5,4,8,3,7]
示例输出:
49
二、问题直观理解
每一条竖线的高度由数组元素值表示,两条竖线之间的距离(索引差)决定了水容器的宽度。
容器能装的水量为:
area = ( right − left ) × min ( height[left] , height[right] ) \text{area} = (\text{right} - \text{left}) \times \min(\text{height[left]}, \text{height[right]}) area=(right−left)×min(height[left],height[right])
我们要在所有可能的线对中寻找最大的这个面积值。
图示
下面是直观的容器示意图(索引 1 和索引 8 形成最大水量容器):
left=1,height=8
right=8, height=7
A
容器
C
水面面积 = (8-1) * min(8,7) = 49
三、解法分析
我们讨论两种解法:
解法一:暴力枚举(Brute Force)
思路
- 枚举所有可能的两条线
(i, j),计算对应容器面积。 - 记录最大值。
时间复杂度
- 枚举所有线对:( O(n^2) )
- 对于大规模输入(如 n > 10^4),会超时。
空间复杂度
- 仅使用常数空间:( O(1) )。
不推荐
解法二:双指针法(Two Pointer)
核心思想
从最左端和最右端开始向中间移动,通过贪心思想逐步逼近最大值。
步骤说明
- 初始化两个指针:
left = 0right = n - 1
- 当前容器面积:
area = (right - left) \\times \\min(height\[left\], height\[right\])
- 更新最大面积。
- 移动较短的一侧指针(因为较短侧限制了高度,移动长侧无法提升面积)。
- 重复直到
left >= right。
双指针移动示意
right pointer left pointer right pointer left pointer alt [若 height[L] < height[R]] loop [直到 L >= R] 计算 area = (R - L) * min(height[L], height[R]) left++ right-- 更新 maxArea
示例走查
height = [1,8,6,2,5,4,8,3,7]
| 步骤 | left | right | min(height[left], height[right]) | 宽度 | 面积 | 当前最大 |
|---|---|---|---|---|---|---|
| 1 | 0 | 8 | min(1, 7)=1 | 8 | 8 | 8 |
| 2 | 1 | 8 | min(8, 7)=7 | 7 | 49 | 49 |
| 3 | 1 | 7 | min(8, 3)=3 | 6 | 18 | 49 |
| ... | ... | ... | ... | ... | ... | 49 |
最终结果:49
四、时间与空间复杂度分析
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 暴力枚举 | O(n²) | O(1) | 简单直观 | 性能极差 |
| 双指针法 | O(n) | O(1) | 高效实用 | 思路需要理解贪心原理 |
五、Java 实现代码
java
public class Solution {
public int maxArea(int[] height) {
int left = 0, right = height.length - 1;
int maxArea = 0;
while (left < right) {
int h = Math.min(height[left], height[right]);
int area = h * (right - left);
maxArea = Math.max(maxArea, area);
// 移动较短边
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return maxArea;
}
}
总结
- 双指针法以 线性时间复杂度 O(n) 找到最优解,是此题的经典最佳方案。
- 核心是通过移动较短边来可能获得更高的容器。
- 理解"面积由短边决定"的原理,是解决此类问题的关键。