给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。并且,你不能倾斜容器。
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
一、双指针法
两个指针分别从数字最左边和最右边开始移动,决定容器中容纳水的最大值的因素为最短的那根线。因此,每次移动短的那根线并保存最大的结果即可。
暗焰之珩:若向内移动短板,水槽的短板 min(h[i], h[j])min(h[i],h[j]) 可能变大,因此水槽面积 S(i, j)S(i,j) 可能增大。若向内移动长板,水槽的短板 min(h[i], h[j])min(h[i],h[j]) 不变或变小,下个水槽的面积一定小于当前水槽面积。“其实可以加一句,无论是移动短板或者长板,我们都只关注移动后的新短板会不会变长,而每次移动的木板都只有三种情况,比原短板短,比原短板长,与原短板相等;如向内移动长板,对于新的木板:1.比原短板短,则新短板更短。2.与原短板相等或者比原短板长,则新短板不变。所以,向内移动长板,一定不能使新短板变长。
代码:
int maxArea(vector<int>& height) {
int i=0, j = height.size()-1, res=0;
while(i < j)
{
res = std::max(res,(j-i) * std::min(height[i], height[j]));
if(height[i]> height[j])
{
j--;
}
else
{
i++;
}
}
return res;
}