leetcode之Container With Most Water

来源:互联网 发布:微信html5制作软件 编辑:程序博客网 时间:2024/06/09 23:05

原题如下:

Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) 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.

http://oj.leetcode.com/problems/container-with-most-water/

思路:该题容易想到的是穷举所有可能并计算其面积,然后选择最大的值返回,这种思路可行但在leetcode上测试时出现超时问题。

看到discuss中的一种最好方法,现将思路描述如下:

        利用两个指针分别指向数组的最左端和最右端,并将其计算面积作为最大面积的初值。然后左右两个指针从两端开始对数组进行遍历,直至两指针相遇遍历结束。在遍历的过程中,计算当前两个端点所组成的面积,并将其与当前最大面积比较,如果比当前最大值大则更新最大值,同时在遍历的过程中,当左端的高度小于右端的高度时,左指针加1,当右端的高度小于左端的高度时,右指针减1,遍历结束后即的到最大面积。

    对上述思路的简单证明:这道题是存在最优解的,上述方法就是一个选优的过程,假设最优解的左端值为left,右端值为right,在上述方法中,由于左右两指针对整个数组扫描了一遍,所以一定存在在某个时刻有一个指针指向了最优解中的一个值。在此基础上只需证明先指向最优解一端的指针一定会在原地等待另一个指针指向最优解的另一端。原因如下:假设两个指针中最先指向最优解一端的为左指针,按照上述方法中的移动原则,如果左指针向前移动,则说明左指针指向的值比当前右指针指向的值小,但这是不可能的,因为如果左指针指向的是比当前右指针指向的值小的话,那么当前左右指针指向的面积将比最优解还要大(因为此时宽度比最优解的宽度要大,而最优解的高度又不可能比当前高度高,左指针限制),出现矛盾,所以,左指针不会移动,它只会等待右指针指向最优解的右端值。综上,按照上述方法,最优解的左右端点一定不会被错过,因此一定能够找到最优解。代码如下:

class Solution {public:    int maxArea(vector<int> &height) {/*int len = height.size();if(len == 0 || len == 1)return 0;int max = min(height[1],height[0]);for(int i = 2; i <len; i++){for(int j = 0; j < i; j++){int temp = min(height[j],height[i]) *(i - j);if(max < temp)max = temp;}}return max;*/int len = height.size();if(len == 0 || len == 1)return 0 ;int i = 0,j = len - 1;int maxValue = (j - i) * min(height[i],height[j]);while (i < j){maxValue = max(maxValue,(j - i) * min(height[i],height[j]));if(height[i] < height[j])i++;else{j--;}}return maxValue;    }
代码中注释部分是穷举所有情况的方法,效率比较低,在leetcode上出现超时,而方法二效率高的原因就是省略的一些无谓的比较(但又不能错过最优解)。

0 0