leetcode 11. 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.

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

首先可以暴力求解,枚举每两个柱子,算他们之间的盛水量,取最大的,时间复杂度:O(n2)O(n^2)

采用双指针法,两个指针分别在首尾,先计算出来此时的水量,然后以下每一步:

  • 假如左指针指向的柱子比右指针指向的柱子低,那么左指针右移
  • 反之右指针左移
  • 更新最大水量

直至两指针相遇。

这个思路在于每次移动指针要移动较低的那个,因为向里移动之后宽度肯定变小,为了能使水量增加,要想办法使最小高度变大,移较低的那个是有可能使水量增加的。反之假如移较高的那个,水量是肯定会减少的。

如何证明最后得出的是最优解?假设存在 [ol,or] 是最优解,但是这一对被扫描的时候漏掉了,也就是说左指针指向 ol,右指针指向 or 这种情况没有发生,那么也就是说在左指针已经扫过 ol 时,右指针还没扫到 or ,或者再反过来,不失一般性,假设当前左指针指向 ol ,右指针指向 pr ,而 pror 的右边(也就是右指针还没扫到 or),此时下一时刻刚好是左指针右移(这样就可以达成条件:漏掉所谓的最优解 ol,or),什么时候左指针会右移?当 h[ol]<h[pl] 时,此时的水量为 h[ol]*(pl-ol),而假设的那个最优解的水量为 min(h(ol),h(or))*(or-ol),其中 (or-ol)<(pl-ol),并且 min(h[ol],h[or])<h[ol],因此这个所谓的最优解是不如 [ol,pl] 的,矛盾!

class Solution {
public:
    int maxArea(vector<int>& height) {
        int sz=height.size();
        int i=0,j=sz-1;
        int res=min(height[i],height[j])*j;
        while(i<j-1){
            if(height[i]<height[j])i++;
            else j--;
            res=max(res,min(height[i],height[j])*(j-i));
        }
        return res;
    }
};
posted @ 2020-05-12 19:26  winechord  阅读(61)  评论(0编辑  收藏  举报