每日OJ题_算法_双指针④_力扣11. 盛最多水的容器
2023-12-14 06:28:28
目录
力扣11. 盛最多水的容器
难度 中等
给定一个长度为?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
class Solution {
public:
int maxArea(vector<int>& height) {
}
};
解析代码
首先想到的是两层循环的暴力解法,时间复杂度是O(N^2),这里采用双指针(对撞指针)的思想优化到O(N):
设两个指针 left , right 分别指向容器的左右两个端点,此时容器的容积 :
v = (right - left) * min( height[right], height[left])?
容器的左边界为 height[left] ,右边界为 height[right] 。
为了方便叙述,假设「左边边界」小于「右边边界」。
- 容器的宽度一定变小。
- 由于左边界较小,决定了水的高度。如果改变左边界,新的水面高度不确定,但是一定不会超过右边的柱子高度,因此容器的容积可能会增大。
- 如果改变右边界,无论右边界移动到哪里,新的水面的高度一定不会超过左边界,也就是不会超过现在的水面高度,但是由于容器的宽度减小,因此容器的容积一定会变小。
由此可见,左边界和其余边界的组合情况都可以舍去。所以可以left++跳过这个边界,继续去判断下一个左右边界。
不断重复上述过程,每次都可以舍去大量不必要的枚举过程,直到left与right相遇。期间产生的所有的容积里面的最大值,就是最终答案。
代码:
class Solution {
public:
int maxArea(vector<int>& height) {
int left = 0, right = height.size() - 1, ret = 0;
while(left < right)
{
int v = (right - left) * min(height[left], height[right]);
ret = max(v, ret);
if(height[left] < height[right]) // 哪个小哪个就往中间移动
{
++left;
}
else
{
--right;
}
}
return ret;
}
};
文章来源:https://blog.csdn.net/GRrtx/article/details/134902502
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!