给定n(n≥2n\ge 2n≥2)个非负整数a1,a2,...,ana_1,a_2,...,a_na1,a2,...,an,其中每一个代表一个坐标点(i,ai)(i,a_i)(i,ai),绘制n条垂线,使得线的两个端点为(i,ai)(i,a_i)(i,ai)和(i,0)(i,0)(i,0)。找到两条线,使得这两条线和x轴所形成的容器能乘最多的水。如下图所示:
Given n non-negative integers a1,a2,...,ana_1,a_2,...,a_na1,a2,...,an , where each represents a point at coordinate (i,ai)(i,a_i)(i,ai). n vertical lines are drawn such that the two endpoints of line i is at (i,ai)(i,a_i)(i,ai) and (i,0)(i,0)(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.
下图是输入为[1,8,6,2,5,4,8,3,7]
所形成的图形
样例:
Input: [1,8,6,2,5,4,8,3,7]
Output: 49
如果枚举所有边,那就有Cn2C_n^2Cn2中可能,也就是时间复杂度为O(n2)O(n^2)O(n2),但是使用贪心法就可以使得时间复杂度变为O(n)O(n)O(n)。
因为:面积=底边的长度*(两边中较低的一条的长度)
要使面积尽可能大,就要使乘法的两个因子尽可能大,所以我们从底边最大处开始,接下来底边只可能比原来的小,想要找到面积更大的,就要使“两边中较低的长度”比原来大。所以要将短的那条边换掉。然后重复该过程。直到左右指针相撞。
因为left和right都在“向中间靠拢”,所以循环次数为n次,时间复杂度为O(n)O(n)O(n)。
完整代码:
class Solution
{
public:
int maxArea(vector<int>& height)
{
int a=0;
int ans=0;
int left=0,right=height.size()-1;
while(left<right)
{
a=(right-left)*(height[left]<height[right]?height[left++]:height[right--]);
ans = ans > a? ans : a;
}
return ans;
}
};