11. 盛最多水的容器(双指针法)

题目描述

leetcode - 11:https://leetcode-cn.com/problems/container-with-most-water/

题目描述 题目描述

解题关键

  • 双指针法
    • 求出当前双指针对应的容器的容量
    • 对应数字较小的那个指针以后不可能作为容器的边界了,将其丢弃,并移动对应的指针。

碎碎念

双指针法顾名思义就是头尾各一个指针,然后逐渐往中间移动找解的过,这样时间复杂度就只有 O(n),这题的理论证明官方说的挺清楚的:
第一步:假设当前左指针和右指针指向的数分别为 xy,假设x ≤ y 同时,两个指针之间的距离为 t 。那么,它们组成的容器的容量为:min(x,y)∗t=x∗t

可以断定,如果保持左指针的位置不变,那么无论右指针在哪里,这个容器的容量都不会超过 x ∗ t 了。注意这里右指针只能向左移动,因为我们考虑的是第一步,也就是指针还指向数组的左右边界的时候。

我们任意向左移动右指针,指向的数为 y1 ,两个指针之间的距离为 t1,那么显然有 t1 < t,并且 min(x,y1)≤min(x,y)

  • 如果 y1y,那么 min(x,y1)≤min(x,y)
  • 如果 y1 > y,那么 min(x,y1)=x=min(x,y)

因此有:min(x,yt)∗t1<min(x,y)∗t

即无论我们怎么移动右指针,得到的容器的容量都小于移动前容器的容量。也就是说,这个左指针对应的数不会作为容器的边界了,那么我们就可以丢弃这个位置,将左指针向右移动一个位置,此时新的左指针于原先的右指针之间的左右位置,才可能会作为容器的边界。

代码

  • 时间复杂度O(N)
  • 空间复杂度O(1)
int maxArea(vector<int>& height) {
    int start = 0;
    int end = height.size()-1;
    int ans = 0;
    while(start<end){
        int min = height[start] < height[end] ? height[start] : height[end];
        ans = ans > min*(end-start) ? ans : min*(end-start);
        height[start] < height[end] ? start++ : end-- ;
    }
    return ans;
}
posted @ 2020-06-02 02:01  _Sleeping  阅读(100)  评论(0)    收藏  举报