Given n non-negative integers a1, a2, ..., an,where each represents a point at coordinate (i, ai). n vertical lines are drawn suchthat the two endpoints of line i is at (i, ai) and(i, 0). Find two lines, which togetherwith x-axis forms a container, such that the container contains the most water.
Note: You maynot slant the container.
O(n)的复杂度。保持两个指针i,j;分别指向长度数组的首尾。如果ai 小于aj,则移动i向后(i++)。反之,移动j向前(j--)。如果当前的area大于了所记录的area,替换之。这个想法的基础是,如果i的长度小于j,无论如何移动j,短板在i,不可能找到比当前记录的area更大的值了,只能通过移动i来找到新的可能的更大面积。
(遍历是无法通过大数据的.)
classSolution {
public:
int maxArea(vector<int> &height){
int max = 0;
int len = height.size();
if(len<2) return 0;
int head=0,tail=len-1;
while (head<tail){
int area =min(height[head],height[tail]);
area *= tail-head;
if (height[head]<height[tail]){
head++;
}else {
tail--;
}
max = max>area?max:area;
}
return max;
}
};
思路来源:http://www.cnblogs.com/lichen782/p/leetcode_Container_With_Most_Water.html
LeetCode 笔记系列二 Container With Most Water
题目: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.
就是说,x轴上在1,2,...,n点上有许多垂直的线段,长度依次是a1, a2, ..., an。找出两条线段,使他们和x抽围成的面积最大。面积公式是 Min(ai, aj) X |j - i|
解法1:大家都能想到的,穷举所有(i,j)可能,找一个最大的。
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 //O(n^2) 2 public static int maxArea(int[] height) { 3 // Start typing your Java solution below 4 // DO NOT write main() function 5 int maxArea = 0; 6 for(int i = 1; i < height.length; i++){ 7 if(height[i] == 0)continue; 8 for(int j = 0; j < i; j++) { 9 int area = area(height,i,j); 10 if(area > maxArea) { 11 maxArea = area; 12 } 13 } 14 } 15 return maxArea; 16 }
不过这样的话无法通过leetcode大集合。
解法2:可以对解法1中的第二个循环中的j做预先判断从而跳过某些情况。在我们检查比i小的各个j时,计算面积的短板不会超过ai本身。平均到距离上,j不会在一定距离上靠近i。
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 public static int maxArea(int[] height) { 2 // Start typing your Java solution below 3 // DO NOT write main() function 4 int maxArea = 0; 5 for(int i = 1; i < height.length; i++){ 6 if(height[i] == 0)continue; 7 int maxPossibleIdx = i - maxArea/height[i]; 8 for(int j = 0; j < i && j <= maxPossibleIdx; j++) { 9 int area = area(height,i,j); 10 if(area > maxArea) { 11 maxArea = area; 12 } 13 } 14 } 15 return maxArea; 16 }
这个方法能够通过大集合。
解法3: O(n)的复杂度。保持两个指针i,j;分别指向长度数组的首尾。如果ai 小于aj,则移动i向后(i++)。反之,移动j向前(j--)。如果当前的area大于了所记录的area,替换之。这个想法的基础是,如果i的长度小于j,无论如何移动j,短板在i,不可能找到比当前记录的area更大的值了,只能通过移动i来找到新的可能的更大面积。
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 public static int maxArea(int[] height){ 2 int maxArea = 0; 3 int i = 0; 4 int j = height.length - 1; 5 if(j <=0)return 0; 6 while(i < j) { 7 int area = area(height, i, j); 8 if(height[i] < height[j]){ 9 i++; 10 11 }else { 12 j--; 13 } 14 if(area > maxArea) maxArea = area; 15 } 16 return maxArea; 17 }