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 and n is at least 2.
思路:
方案一:暴力穷举,题目的意思就是求两条线段与X轴组成的开口的图形所能容纳的最大的水,想象成一个水桶,水桶最短的木板决定了所能容纳水的体积,这里也是一样的,起决定作用的是最短的一条线段,也就是说在线段之间距离相等的情况下,所要求的就是min(ai,aj)*(ai-aj);O(n^2)的解法很直观,穷举所有线段的组成可能,计算其中最大的面积就是所要求的返回值
方案二:使用两个指针,L指向第一个线段,R指向最后一个线段,此时L与R距离最长,我们用L于R中较短的线段可以算出此时的面积,接下来我们分析一下,因为面积是由最短的线段决定的,而且此时L与R的距离已经最长了,为(R-L)。假设L<R,显然我们之前算的面积是L*(R-L)。下一步显然需要移动L或R,怎么移动呢,如果我们将R左移,因为L是较短的线段,左移之后最长的面积是L*(R'-L),由于L没变,而(R'-L)显然小于(R-L),所以移动长的线段是没有用的,因此我们应该移动短的线段L,同理,在L和R不断向中间移动的时候,我们每次始终选择短的一条线段移动,最后L=R时结束,复杂度是O(n).
class Solution {
public:
int maxArea(vector<int>& height) {
if (height.empty())
return 0;
int len = height.size();
int max = 0;
int i = 0, j = len - 1;
while(i < j)
{
int h = height[i] < height[j] ? height[i] :height[j];
int area = h * (j - i);
if (max < area) max = area;
if (h == height[i])
++i;
else
--j;
}
return max;
}
};