目录
题目链接:11. 盛最多水的容器 - 力扣(LeetCode)
话不多说,直接上强度,这是一道使用双指针的解法的题目,并且是一个很考验思维的题目,中等题难度确实是上来了。我们来看看吧~~~
题目链接:11. 盛最多水的容器 - 力扣(LeetCode)
注:下述题目描述和示例均来自力扣
题目描述
给定一个长度为 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 <= 10^5
0 <= height[i] <= 10^4
思路概要
这道题是求解能够容纳最多水的容器,即求解最大的容器面积。
我们可以使用双指针的方法来逐步缩小搜索范围。初始时,左指针指向数组的第一个元素,右指针指向数组的最后一个元素。
然后,我们计算当前指针构成的容器的面积,即底边长度为指针之间的距离,高度为指针指向的较小元素的值。这个面积就是当前容器的容量。
接下来,我们将指针向内移动。由于底边长度减少,要使容器面积增大,我们需要选择高度更高的边界来作为新的边界。所以,我们将较小的边界的指针向内移动一位。
我们重复这个过程直到左指针超过右指针。在这个过程中,我们不断更新最大的容器面积结果。
最后,我们返回最大的容器面积。
这种双指针的方法可以保证我们找到最大的容器面积,并且时间复杂度为O(n),其中n为输入数组的长度。这是因为我们每次移动指针时,都会排除掉一些无效的容器,从而减少搜索范围,直到找到最大的容器面积。
解法一:双指针
思路
我们的目标是找到能够盛水最多的两个边界,即找到最大的容器。代码中使用了双指针的方法来不断缩小搜索范围。
-
初始化左指针left为数组的第一个元素的下标,右指针right为数组的最后一个元素的下标。
-
在while循环中,判断左指针left是否小于右指针right,如果是则进行下一步,否则退出循环。
-
计算当前的容器面积,即底边长度为(right - left),高度为左右指针指向的较小的元素。
-
更新最大面积result为当前面积和最大面积result中的较大值。
-
如果左指针指向的元素小于右指针指向的元素,则左指针右移一位;否则右指针左移一位。
-
返回最大面积result。
该算法的时间复杂度为O(n),其中n为输入数组的长度。算法中使用了双指针法,通过不断缩小搜索范围来寻找最大的容器,避免了暴力枚举所有可能的容器。
代码实现
class Solution {
public int maxArea(int[] height) {
// 利用双指针
int left = 0;
int right = height.length - 1;
// 开始循环判断
// 在这里的时候,left == right是没有用的
int result = 0;
while (left < right) {
// 底边长度为right - left
// 高度是他们之间最小的那一个
int area = (right - left) * (height[left] < height[right] ? height[left++] : height[right--]);
result = area > result ? area : result;
}
return result;
}
}
就这个执行效率来说也是拉满了。
总结
非常的ezezez,大家放心食用,学会了之后确实是会有所收获的。