本文我们来讲解LeetCode 第11题:盛最多水的容器 —— 详解与实现。
引言
大家好!今天咱们要讨论的是LeetCode上的第11题——盛最多水的容器。这个题目表面看起来就像是个简单的几何问题,但实际上却蕴含着许多算法上的奥妙。接下来,我将带你一起揭开这个问题的神秘面纱。
题目描述
题目要求给定一个数组 height
,其中每个元素表示一条垂直的线段的高度。每条线段的宽度是1。我们需要找出两条线段,使得它们与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
思路解析
要解这个题,咱们得动点脑筋。显然,光用暴力破解法是行不通的,咱们得想点聪明的办法。于是,“双指针”大法便横空出世了。
双指针解法
步骤详解
- 初始化两个指针:一个指向数组的开头(
left
),一个指向数组的末尾(right
)。 - 计算当前容器的容量:用两个指针指向的高度的较小值乘以它们之间的距离。
- 移动指针:为了找到可能更大的容器,我们需要移动指针。移动哪个指针呢?当然是移动较矮的那个指针,这样才有可能找到一个更高的线段,增加容量。
- 重复以上步骤,直到两个指针相遇。
动图演示
代码实现
讲了这么多,咱们用Java代码实现一下:
public class Solution {
public int maxArea(int[] height) {
int left = 0;
int right = height.length - 1;
int maxArea = 0;
while (left < right) {
int minHeight = Math.min(height[left], height[right]);
int width = right - left;
int currentArea = minHeight * width;
maxArea = Math.max(maxArea, currentArea);
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return maxArea;
}
}
代码详解
我们逐行来看一下代码的实现逻辑:
-
初始化变量:
int left = 0; int right = height.length - 1; int maxArea = 0;
left
初始化为0,指向数组的第一个元素。right
初始化为height.length - 1
,指向数组的最后一个元素。maxArea
初始化为0,用于记录最大面积。
-
循环计算面积:
while (left < right) { int minHeight = Math.min(height[left], height[right]); int width = right - left; int currentArea = minHeight * width; maxArea = Math.max(maxArea, currentArea);
- 使用
while (left < right)
循环,直到两个指针相遇。 minHeight
计算当前指针所指高度的最小值。width
计算两个指针之间的宽度。currentArea
计算当前的容器面积。- 使用
Math.max
更新最大面积maxArea
。
- 使用
-
移动指针:
if (height[left] < height[right]) { left++; } else { right--; }
- 如果
left
指针的高度小于right
指针的高度,移动left
指针。 - 否则,移动
right
指针。
- 如果
举例说明
咱们用几个例子来看看这个算法是怎么工作的:
-
示例1:
- 输入:
[1,8,6,2,5,4,8,3,7]
- 过程:
- 初始指针:
left = 0
,right = 8
,面积min(1,7) * (8-0) = 7 * 8 = 49
- 移动
left
,因为1 < 7
,面积变为min(8,7) * (8-1) = 7 * 7 = 49
- 继续移动
right
,面积变为min(8,3) * (7-1) = 3 * 6 = 18
- ……(省略中间过程)
- 最终得到最大面积为49。
- 初始指针:
- 输入:
-
示例2:
- 输入:
[4,3,2,1,4]
- 过程:
- 初始指针:
left = 0
,right = 4
,面积min(4,4) * (4-0) = 4 * 4 = 16
- 移动
right
,面积变为min(4,1) * (3-0) = 1 * 3 = 3
- 继续移动
right
,面积变为min(4,2) * (2-0) = 2 * 2 = 4
- ……(省略中间过程)
- 最终得到最大面积为16。
- 初始指针:
- 输入:
-
示例3:
- 输入:
[1,2,1]
- 过程:
- 初始指针:
left = 0
,right = 2
,面积min(1,1) * (2-0) = 1 * 2 = 2
- 移动
right
,面积变为min(1,2) * (1-0) = 1 * 1 = 1
- 最终得到最大面积为2。
- 初始指针:
- 输入:
总结
我们通过双指针的方法解决了盛最多水的容器问题。这种方法不仅简洁高效,而且通过移动指针来不断逼近最优解,避免了暴力破解的低效。希望这篇博客能够帮助大家更好地理解和掌握这道题目。下次遇到类似的问题时,别忘了用双指针大法来试试看哦!
如果本文对您有所帮助的话,请收藏文章、关注作者、订阅专栏,感激不尽。