- LeetCode 热题 100 - 两数之和
- 字母异位词分组
- 最长连续序列
- 移动零
- 盛最多水的容器
- 三数之和
- 接雨水
- 找到字符串中所有字母异位词
- 无重复字符的最长子串
- 和为 K 的子数组
- 滑动窗口最大值
盛最多水的容器
class 贪心,数组,双指针给定一个长度为 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
解法一:
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
if (!height || height.length < 2) {
return 0;
}
let max = 0;
let res = 0;
for (let i = 0; i < (height.length - 1); i++) {
for (let j = i + 1; j < height.length; j++) {
if (height[i] < height[j]) {
res = height[i] * (j - i);
} else {
res = height[j] * (j - i);
}
if (res > max) {
max = res;
}
}
}
return max;
};
耗时久,性能差
这个问题是著名的“盛水最多的容器”问题,可以通过双指针法来高效地解决。该算法的关键在于逐步缩小范围,同时记录能够容纳的最大水量。
解决方案概述
给定一个整数数组 height
,我们需要找到两个索引 i
和 j
(其中 i < j
),使得 min(height[i], height[j]) * (j - i)
的值最大。这就是容器的最大水容量。
算法步骤
初始化双指针:
设置两个指针,左指针
left
初始化为数组的起始位置0
,右指针right
初始化为数组的终止位置n-1
,其中n
是数组的长度。计算当前水容量:
在每一步中,计算由
left
和right
指针所确定的容器的水容量:min(height[left], height[right]) * (right - left)
。如果这个容量比目前记录的最大容量要大,就更新最大容量。
移动指针:
由于水容量受限于短板(较短的那一边),我们选择移动高度较小的一端指针(即
height[left]
和height[right]
中较小的那一个)来尝试寻找更长的高度。如果
height[left] < height[right]
,就把left
指针右移(left++
),否则就把right
指针左移(right--
)。重复步骤2和步骤3,直到两个指针相遇。
输出结果:
当两个指针相遇时,已经找到了最大水容量,输出这个最大值。
代码实现
def maxArea(height):
# 初始化双指针
left, right = 0, len(height) - 1
max_water = 0
while left < right: # 计算当前容器的水容量
current_water = min(height[left], height[right]) * (right - left)
# 更新最大水容量
max_water = max(max_water, current_water)
# 移动指针
if height[left] < height[right]:
left += 1
else:
right -= 1
return max_water# 示例测试heights = [1,8,6,2,5,4,8,3,7]print(maxArea(heights)) # 输出: 49
复杂度分析
时间复杂度:O(n),其中
n
是数组的长度。每个元素最多被访问一次。空间复杂度:O(1),只使用了常量级别的额外空间。
示例
对于 heights = [1,8,6,2,5,4,8,3,7]
,上述代码将输出 49
。这对应于垂线索引 1
和 8
,它们之间的距离是 7
,较短的垂线高度是 7
,因此水容量是 7 * 7 = 49
。
这个算法通过聪明地选择指针移动来高效地找到最优解,并且避免了冗余计算。