题目
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 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
示例 3:
输入:height = [4,3,2,1,4]
输出:16
示例 4:
输入:height = [1,2,1]
输出:2
“错误”解答
思路
用一个二维数组保存以0到ai为起点,再以0到ai为终点计算出来的结果,也就是熟知的两个for循环。错误点: 时间复杂度太高
需要的头文件
limits.h
代码
/*
* @lc app=leetcode.cn id=11 lang=cpp
*
* [11] 盛最多水的容器
*/
// @lc code=start
#include <string>
#include <vector>
using namespace std;
class Solution
{
public:
int maxArea(vector<int> &height)
{
int hlength = height.size();
int maxvol = 0;
//二维数组
vector<vector<int>> container(hlength);
for (int i = 0; i < container.size(); i++)
{
container[i].resize(hlength);
}
for (int i = 0; i < hlength; i++)
{
for (int j = 0; j < hlength; j++)
{
if (i == j || i > j)
{
continue;
}
else
{
container[i][j] = min(height[i], height[j]) * abs(i - j);
if (container[i][j] > maxvol)
{
maxvol = container[i][j];
}
}
}
}
return maxvol;
}
};
// @lc code=end
时间复杂度和空间复杂度
- 时间复杂度:for循环嵌套,所以为 O(n2) 。
- 空间复杂度:开辟了二维数组空间,所以为 O(n2) 。
正确解答:双指针法
思路
头指针和尾指针向中间“逼近”。
可行性分析:
假设当前左指针和右指针指向的数分别为x和y。不失一般性,我们假设x≤y。同时,两指针之间的距离为t。那么,它们组成的容器的容量为:
(
x
+
y
)
∗
t
(x+y)*t
(x+y)∗t
假设固定左指针。(即x不变) 想要上式增大,我们只能考虑增大y和t。
- 对于t:因为指针只能向“里”移动,所以t必定是逐渐减小的。
- 对于y:如果y增大,短板仍然为x,增大y不能增大容量;如果y减小,情况更糟糕,短板变成了y,容量比之前还要小。
- 综上,容量只能不变或变小,不可能变大。所以,不论右指针怎么移动,都不能增大容量,这个时候左指针所在的位置就失去意义了,我们必须让短板变长,而不是让长板有可能变短。
通过以上分析,我们可以得出结论:让较短的一边向内缩进,用一个变量记录最大值,这道题就解决了。
需要的头文件
vector
代码
/*
* @lc app=leetcode.cn id=11 lang=cpp
*
* [11] 盛最多水的容器
*/
// @lc code=start
#include <vector>
using namespace std;
class Solution
{
public:
int maxArea(vector<int> &height)
{
int hlength = height.size();
//双指针
int lp = 0, rp = hlength - 1;
//记录最大容量
int maxvol = 0;
while (lp < rp)
{
//公式计算
int vol = min(height[lp], height[rp]) * (rp - lp);
maxvol = max(maxvol, vol);
//小的往里进1,数学原理已经解释
if (height[lp] <= height[rp])
{
lp++;
}
else
{
rp--;
}
}
return maxvol;
}
};
// @lc code=end
时间复杂度和空间复杂度
- 时间复杂度:检查height数组的一半元素,n为height数组长度。所以为 O(n) 。
- 空间复杂度: O(1) 。
反思与总结
- 此类问题用双指针法。