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.
The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
Example:
Input: [1,8,6,2,5,4,8,3,7]
Output: 49
题解
题意:一组数组a[],求两个索引x,y,使得 (y-x)*min(a[x],a[y]) 最大
一开始的方法,暴力:
1 class Solution { 2 public: 3 int maxArea(vector<int>& height) { 4 int ans = 0, size = height.size(); 5 for (int i = 0; i < size; i++) { 6 int tmp = 0, ht = height[i]; 7 for (int j = size - 1; j > i && ht*(j - i) > tmp; j--) 8 tmp = max(tmp, min(ht, height[j])*(j - i)); 9 ans = max(tmp, ans); 10 } 11 return ans; 12 } 13 };
后来看了下题解发现可以这样:设置两个头尾指针向中间移动取值更新答案
1 class Solution { 2 public: 3 int maxArea(vector<int>& height) { 4 int s = 0, e = height.size() - 1, ans = 0; 5 while (s != e) { 6 ans = max(ans, min(height[s], height[e])*(e - s)); 7 if (height[s] < height[e]) 8 s++; 9 else e--; 10 } 11 return ans; 12 } 13 };
(每次改变较短边的索引,保证这种移动方式比改变较长边得到的答案一定好,而每一个最优解都能从初始状态通过移动两端指针得到,这就证明了正确性)
然而还是慢!下面的是翻了别人的帖子看到的题解,就是个小优化,快了4ms吧,但排名上升了很多
1 class Solution { 2 public: 3 int maxArea(vector<int>& height) { 4 int s = 0, e = height.size() - 1, ans = 0; 5 while (s != e) { 6 int h = min(height[s], height[e]); 7 ans = max(ans, h*(e - s)); 8 while (height[s] <= h && s < e) 9 s++; 10 while (height[e] <= h && s < e) 11 e--; 12 } 13 return ans; 14 } 15 };