Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.
Subscribe to see which companies asked this question
题目大意:给出n个数,每个数代表一个高度,给两个木板间倒水,问能存储的水截面最多是多大。
一个直接的思路:枚举可能存在最优解的位置找最大
如何枚举?
int i=0,j=len-1
首先,设两个游标分别位于height数组的起始端和末尾端,那么假设当前最优的情况下,储水截面是min(height[i],height[j])*(j-i);
那么只要枚举两个游标位置,在可能产生最优解的位置,每次不断更新取最大值即可。
所谓可能产生最优解的位置是这样的:
只要保证i<j那么j-i>0,解就是合法的。
假设当前左侧最大高度为lmax,右侧最大高度为rmax,当前最大截面面积是ret;
那么如果要想让新获得的面积大于ret,那么必然要找新的能够大于lmax的左侧最大值,和新的能大于rmax的右侧最大值
因为如果新的高度是小于lmax或者小于rmax的情况下,宽j-i减小,但是高没有增大,所以乘积一定会比上一次的ret小。
所以可能存在最优解的情况是,尽管这一次宽j-i减小了,但是高min(height[i],height[j])增大了,所以乘积有可能比上一次的ret大。
在这个前提下,不断去找右侧的最大和左侧的最大高度,然后求乘积更新最大值即可。
class Solution {
public:
int maxArea(vector<int>& height)
{
int ret=0;
int len=height.size();
int i=0,j=len-1;
int lmax=height[i],rmax=height[j];
while(i<j)
{
ret=max(ret,min(lmax,rmax)*(j-i));
if(lmax<rmax)
{
while(i<j&&height[i]<=lmax)
i++;
if(i<j)
lmax=height[i];
}
else
{
while(j>i&&height[j]<=rmax)
j--;
if(j>i)
rmax=height[j];
}
}
return ret;
}
};