题目描述:
- 给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
示例:
输入: [1,8,6,2,5,4,8,3,7]
输出: 49
双指针法:
思路:寻找每一个垂直线可盛水的最大容积,然后求出所有最大容积;
- 寻找每一个垂直线最大容积方法:固定垂直线 i , 然后将垂直线数组从后向前遍历,求出最大容积(注意:如果出现垂直线 “j” 大于垂直线 “i” 即刻终止循环);
- 如果每一个垂直线 “j” 小于垂直线 “i”,则需要计算每一个 “j” 对应容积,求出最大容积;
int maxArea(vector<int>& h)
{
int m_iOut = 0;
int m_iMaxi = 0;
for (int i = 0; i < h.size() - 1; i++)
{
int j = h.size() - 1;
m_iMaxi = (j - i) * min(h[i], h[j]);
for (; j > i; j--)
{
if (h[j] >= h[i])
{
m_iMaxi = max(m_iMaxi , (j - i) * h[i]);
break;
}
else
{
m_iMaxi = max(m_iMaxi, (j - i) * h[j]);
}
}
m_iOut = max(m_iOut, m_iMaxi);
}
return m_iOut;
}
改进版:由于计算具有对称性(从前向后计算和从后向前计算相同),可通过双指针进行同时计算 i 和 j 对应的最大值,小指针向中间靠拢;
int maxArea(vector<int>& h)
{
int m_iMax = 0;
int i = 0;
int j = h.size() - 1;
while (i < j)
{
if (h[i] < h[j])
{
m_iMax = max(m_iMax, (j - i)*h[i]);
i++;
}
else
{
m_iMax = max(m_iMax, (j - i)*h[j]);
j--;
}
}
return m_iMax;
}