题目来源:[LeetCode]11. 盛最多水的容器

难度标签:中等

算法标签:双指针,DP,枚举

题目描述:

给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

[LeetCode]11. 盛最多水的容器_时间复杂度

示例:

输入:[1,8,6,2,5,4,8,3,7]
输出:49

题目思路:

有题可知我们的目标是明确能盛如多少水量,此时问题转化为水量在整个可能存在的等式当中的关系。
实际读题之后我们发现,水量受到​​​宽度​​​,​​高度​​两个要素影响,且不是单纯递增关系,因此排出本来设想的贪心。

1.我们用最直接得想法可以瞄准暴力,列举所有可能存在再判断.
此时我们将目光瞄准为求最大水量的话,可以得到等式​​​max_area=max(max_area,min(height[l],height[r])*(r-l))​​​ 最大水量等于​​所有情况中(现存宽度乘两边高度中相对较低的一边)的最大值​​。

2.有了这个表达式之后剩下得任务则转换为降低降低频次。
依据题意两边的概念我们很容易想到双指针移动的方式,且因为等式高度关系,每次移动保持寻找​​​更高值​​即可,找到尽可能最大的二位面积即可。

题目代码:

解法一:双指针,动态规划

时间复杂度:o(n)
状态 :通过

class Solution {
public:
int maxArea(vector<int>& height) {
int max_area=0,l=0,r=height.size()-1;//max_area假设面积,l,左端点,r右端点
while(l<r)
{
max_area=max(max_area,min(height[l],height[r])*(r-l));//面积等式
if(height[l]<height[r])l++;//双指针移动,尽可能保持最大面积
else r--;
}
return max_area;
}
};

解法二:蛮力算法

时间复杂度:o(n^2)
状态 :超时,48 / 50 个通过测试用例,显然能过掉大部分数据,在oi赛制还是能拿分嘛

class Solution {
public:
int maxArea(vector<int>& height) {
int max_area=0;
for(int i=0;i<=height.size()-1;i++)
for(int j=i;j<=height.size()-1;j++)
max_area=max(max_area,(j-i)*min(height[i],height[j]));//暴力列举所有情况判断
return max_area;
}
};