11. 盛最多水的容器(双指针法)
题目描述
leetcode - 11:https://leetcode-cn.com/problems/container-with-most-water/
解题关键
- 双指针法
- 求出当前双指针对应的容器的容量
- 对应数字较小的那个指针以后不可能作为容器的边界了,将其丢弃,并移动对应的指针。
碎碎念
双指针法顾名思义就是头尾各一个指针,然后逐渐往中间移动找解的过,这样时间复杂度就只有 O(n),这题的理论证明官方说的挺清楚的:
第一步:假设当前左指针和右指针指向的数分别为 x 和 y,假设x ≤ y 同时,两个指针之间的距离为 t 。那么,它们组成的容器的容量为:min(x,y)∗t=x∗t
可以断定,如果保持左指针的位置不变,那么无论右指针在哪里,这个容器的容量都不会超过 x ∗ t 了。注意这里右指针只能向左移动,因为我们考虑的是第一步,也就是指针还指向数组的左右边界的时候。
我们任意向左移动右指针,指向的数为 y1 ,两个指针之间的距离为 t1,那么显然有 t1 < t,并且 min(x,y1)≤min(x,y):
- 如果
y1≤y,那么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;
}

浙公网安备 33010602011771号