题目
盛最多水的容器
题面
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jZYGEwWD-1672845953315)(C:\Users\wangz\AppData\Roaming\Typora\typora-user-images\image-20220626183259023.png)]
关键词
双指针
思路
维护左右双指针表示这个容器的左右边界,
然后一边移动指针一边记录容器的最大值:面积等于底×高,底:d = rp - lp ,高:h = min(height[lp],height[rp])。
关键之处在于什么情况下移动指针:移动低的那一边界的指针,左边低则lp++,右边低则rp–
可以用反证法证明:
假设height[lp]<height[rp],此时面积area=heitht[lp]*d
此时我们移动右边界rp,rp* = rp-1;
这时候会有三种情况:
height[rp*] < height[rp]
height[rp*] = height[rp]
height[rp*] > height[rp]
对于第一种情况,height[rp*] < height[rp]:
此时,底:d1 = rp* - lp ,高:h1 = min(height[lp],height[rp*]),area1 = d1*h1
有d1<d,h1<=h,area1<area
对于第二种情况,height[rp*] = height[rp]:
此时,底:d2 = rp* - lp ,高:h2 = height[lp],area2 = d2*h2
有d2<d,h2=h,area2<area
对于第三种情况,height[rp*] > height[rp]:
此时,底:d3 = rp* - lp ,高:h3 = height[lp],area3 = d3*h3
有d3<d,h3<=h,area3<area
故对于以上这三种情况,移动右指针都会使面积变小,由反证法可以知道移动左指针可能会使面积变大
代码
class Solution {
public:
int maxArea(vector<int>& height) {
int lp,rp;
lp = 0;
rp = height.size()-1;
int area;
int maxarea = -1;
while(lp<rp){
area = min(height[lp],height[rp])*(rp-lp);
maxarea = max(area,maxarea);
if(height[lp]<=height[rp])
lp++;
else
rp--;
}
return maxarea;
}
};
总结
双指针问题一般是通过设置两个指针对数组进行扫描解决某些具体问题,分快慢指针(相同方向),对撞指针(相反方向)这两种。