Leetcode#11 Container With Most Water

原题地址

 

最朴素的想法就是,枚举容器的左边界和右边界,总能找到解,不过时间复杂度是O(n^2)的。

 

改进I:从左向右枚举左边界,在此基础上从右向左枚举右边界,一旦右边界高度>=左边界高度就可以停止枚举了,因为继续枚举下去找到的矩形肯定面积更小。

比如下图,左边界在位置0,高度为height[0]=3,那么,右边界枚举到位置5就可以停止了(height[5]=4 >= 3=height[0])。

     |
| |
| | |
| | | | | |
| | | | | | |
+-+-+-+-+-+-+
0 1 2 3 4 5 6
^ ^
左边界 右边界

 

改进II:

在改进I中,要从左到右枚举左边界,但是左边界是否要一直枚举到最右边呢?当然不是。

看下图,假设现在枚举到了这个位置:左边界高度是2,右边界高度也是2。

     |
| |
| | |
| | | | | |
| | | | | | |
+-+-+-+-+-+-+
0 1 2 3 4 5 6
^ ^
左边界 右边界

那么,左边界在以后向右移动的时候,凡是高度小于等于2的位置都不用考虑了(图中位置3、4),因为肯定不会超过当前这个矩形的面积。

所以,每次枚举的时候根据右边界高度更新这个阈值,以后遇到阈值低于这个的左边界就不用考虑了。

 

改进III

在改进II中,先确定左边界,然后去枚举右边界,同时右边界又对左边界的选择有一定影响。仔细想想,左右边界本身没有区别,所以可以从两头分别开始枚举,更新阈值。如果左边界比右边界矮,左边界决定了最终矩形的高度,以后不会再有比这个矩形矮并且面积更大的矩形出现了,所以让左边界向右移动一个单位。同理如果右边界比左边界矮,右边界向左移动一个单位。

这就是最终的算法了。

 

代码:

 1 int maxArea(vector<int> &height) {
 2         int l = 0;
 3         int r = height.size() - 1;
 4         int res = 0;
 5         
 6         while (l <= r) {
 7             res = max(res, (r - l) * min(height[l], height[r]));
 8             if (height[l] < height[r])
 9                 l++;
10             else
11                 r--;
12         }
13         
14         return res;
15 }

 

posted @ 2015-01-28 11:52  李舜阳  阅读(183)  评论(0编辑  收藏  举报