给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
示例:
输入: [1,8,6,2,5,4,8,3,7] 输出: 49
思路1:
常见思路,一个指向数组的begin,一个指向数组的end,盛水的面积为begin-end 乘以 min(begin,end);因此依次分别从头和尾部遍历,双重for。
class Solution {
public:
int maxArea(vector<int>& height) {
if(height.size() == 0)
return 0;
int max = 0;
for(int i=0;i<height.size();i++)
for(int j=height.size()-1;j>i;j--)
{
int m = height[i]>height[j]?height[j]:height[i];
int length = j-i;
if(max < m*length)
max = m*length;
}
return max;
}
};
思路二:
思路和思路一一样,只不过强化双指针的概念,用一个while来写。下标一个指向数组的nLeft,一个指向数组的nRight,盛水的面积为nLeft-nRight乘以 min(nLeft,nRight),此时nLeft和nRight的变化规则为:当前下标nLeft和nRight所对应的高度,做比较,谁小,谁向数组里面靠近。
class Solution {
public:
int maxArea(vector<int>& height) {
if (height.size() < 2)
{
return 0;
}
int nLeft = 0;
int nRight = height.size() - 1;
int nMaxArea = 0;
while (nLeft < nRight)
{
int nLeftVal = height[nLeft];
int nRightVal = height[nRight];
int nVal = nLeftVal < nRightVal ? nLeftVal:nRightVal;
if (nMaxArea < nVal * (nRight - nLeft))
{
nMaxArea = nVal * (nRight - nLeft);
}
if (nLeftVal < nRightVal)
{
nLeft++;
}
else
{
nRight--;
}
}
return nMaxArea;
}
};