双指针法是一种求解思想,它不具体指某一种算法。双指针法在求解数组、链表相关的问题时使用的很多,在数组有序时尤甚。
常用的双指针法类型有対撞指针和快慢指针,前者让两个指针分别指向线性空间的头和尾,按照一定的条件向中间慢慢靠近直至两者相遇,算法结束;后者则是让两个指针从同一侧出发,按照不同的步长向前迈进。快慢指针的算法题我做过一道关于求解链表中是否存在环路的问题,那道题使用了快慢指针,今天这道题则是対撞指针。
题目如下:
求解思路如下:
/*
下面这个代码效率不是最高的,应该还有其他大神有更好的方法。
其实这道题的思路比较简单,就是在判断容器最多能放下多少水:
有左右的长度width, 也有高度height(这里要考虑短板效应),两者乘积就当做能放下水的体积了。
高度的求解很简单,就是对应位置的木板中高度的较小者,但是具体要用哪两块作为左右边界就是要求解的问题了。
将双指针指向两端,这是双指针的初始化位置。
接下来就是核心思路:
1.当前两指针之中指向的较矮的那个木板,是限制容积的“短板”
2.要想探索可能存在的更大容积,我们要寄希望于改善短板
3.那么将短板向中间(未探索区域)移动一步看能否获得更好的解
4.向中间移动的过程中宽度width在减小,所以如果板子没有变长,那这一定不是最优解,可以直接指向下一个
*/
int maxArea(vector<int>& height) {
/*initialize the head and tail pointers*/
int Head = 0;
int Tail = height.size() - 1;
/*initialize the MaxArea and Height*/
int Height = min(height[Head], height[Tail]);
int MaxArea = (Tail - Head) * Height;
while(Head < Tail)
{
while(height[Head] <= Height && Head < Tail)
++Head;
while(height[Tail] <= Height && Head < Tail)
--Tail;
Height = min(height[Head], height[Tail]);
MaxArea = max(MaxArea, (Tail - Head) * Height);
}
return MaxArea;
}