您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 如何编写代码实现盛最多水的容器
## 问题描述
给定一个长度为 `n` 的非负整数数组 `height`,其中每个元素代表坐标轴上的一个点 `(i, height[i])`。我们需要找到两条垂直线,使得它们与x轴共同构成的容器可以容纳最多的水。

*示意图说明:红色垂直线代表选定的两条线,阴影部分代表可以盛放的水量*
## 问题分析
### 关键要素
1. **容器边界**:由数组中的两个元素决定
2. **容器高度**:由两个边界中较矮的那个决定
3. **容器宽度**:两个边界在数组中的索引之差
4. **盛水量公式**:`min(height[left], height[right]) * (right - left)`
### 示例
```python
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:选择第2个(高度8)和第9个(高度7)的线,盛水量 = min(8,7) * (7-1) = 7 * 7 = 49
def maxArea_brute(height):
max_area = 0
n = len(height)
for i in range(n):
for j in range(i+1, n):
area = min(height[i], height[j]) * (j - i)
max_area = max(max_area, area)
return max_area
def maxArea(height):
left, right = 0, len(height) - 1
max_area = 0
while left < right:
area = min(height[left], height[right]) * (right - left)
max_area = max(max_area, area)
if height[left] < height[right]:
left += 1
else:
right -= 1
return max_area
当剩余宽度乘以当前最大可能高度(数组中的最大值)小于已获得的最大面积时,可以提前终止。
def maxArea_optimized(height):
left, right = 0, len(height) - 1
max_area = 0
max_h = max(height)
while left < right:
area = min(height[left], height[right]) * (right - left)
max_area = max(max_area, area)
if height[left] < height[right]:
left += 1
else:
right -= 1
# 提前终止判断
if max_area >= max_h * (right - left):
break
return max_area
移动指针时,可以跳过那些比当前边界更矮的线。
def maxArea_skip(height):
left, right = 0, len(height) - 1
max_area = 0
while left < right:
h = min(height[left], height[right])
max_area = max(max_area, h * (right - left))
# 跳过更矮的线
while left < right and height[left] <= h:
left += 1
while left < right and height[right] <= h:
right -= 1
return max_area
height[0] * (n-1)
def maxArea_defensive(height):
if not height or len(height) < 2:
return 0
# 其余逻辑与之前相同
...
assert maxArea([1,1]) == 1
assert maxArea([4,3,2,1,4]) == 16
assert maxArea([1,2,1]) == 2
assert maxArea([]) == 0
assert maxArea([10000] * 10000) == 10000 * 9999
assert maxArea([0,0,0,0]) == 0
import random
large_input = [random.randint(0, 10000) for _ in range(100000)]
# 应能在1秒内完成
public int maxArea(int[] height) {
int left = 0, right = height.length - 1;
int maxArea = 0;
while (left < right) {
int area = Math.min(height[left], height[right]) * (right - left);
maxArea = Math.max(maxArea, area);
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return maxArea;
}
int maxArea(vector<int>& height) {
int left = 0, right = height.size() - 1;
int max_area = 0;
while (left < right) {
max_area = max(max_area, min(height[left], height[right]) * (right - left));
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return max_area;
}
一个更复杂的变种问题,需要计算所有凹陷处能接的雨水量。
def trap(height):
left, right = 0, len(height) - 1
left_max = right_max = 0
result = 0
while left < right:
if height[left] < height[right]:
if height[left] >= left_max:
left_max = height[left]
else:
result += left_max - height[left]
left += 1
else:
if height[right] >= right_max:
right_max = height[right]
else:
result += right_max - height[right]
right -= 1
return result
在直方图中寻找最大矩形面积,需要使用单调栈解决。
方法 | 时间复杂度 | 空间复杂度 | 实际运行时间(1e5数据) |
---|---|---|---|
暴力法 | O(n²) | O(1) | >10s |
双指针法 | O(n) | O(1) | ~0.01s |
优化双指针法 | O(n) | O(1) | ~0.008s |
本文详细介绍了盛最多水容器问题的多种解决方案,从暴力法到最优的双指针法,并提供了多个优化版本和不同语言实现。通过理解这个问题的解决过程,可以掌握双指针类问题的通用解法思路。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。