常见双指针分为两种:
一般用于顺序结构中,也称左右指针。
又称龟兔赛跑算法,其基本思想就是使用两个移动速度不同的指针在数组或链表等序列结构上移动。
这种方法对于处理环形链表或数组非常有用。其实不单单是环形链表或者数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使用快慢指针的思想。
快慢指针的实现方法有很多种,最常用的一种就是:
【数组分块】是非常常见的一种题型,主要就是根据一种划分方式,将数组的内容分成左右两部分。这种类型的题,一般就是使用【双指针】来解决。


算法思路:
1.初始化 cur=0(用来遍历数组),dest=-1(指向非零元素序列的最后一个位置。因为刚开始我们不知道最后一个非零元素在什么位置,因此初始化为 -1)
2.cur 依次往后遍历每个元素,遍历到的元素会有下面两种情况:
class Solution
{
public:
void moveZeroes(vector<int>& nums)
{
for(int dest=-1,cur=0;cur<nums.size();cur++)
{
if(nums[cur])//不等于0
swap(nums[++dest],nums[cur]);
}
}
};这里用到的方法是我们学习 【快排算法】的时候,【数据划分】过程的重要一步。如果将快排算法拆解的话,这一小段代码就是实现快排算法的【核心步骤】。
博主笔记(字迹有点丑,请大家见谅):



1.初始化两个指针 cur=0,dest=0,
2.找到最后一个复写的数:
3.判断 dest 是否越界到 n 的位置:
如果越界,执行下面三步:
4.从 cur 位置开始往前遍历原数组,依次还原出复写后的结果数组:
先判断 cur 位置的值:
cur--,复写下一个位置
class Solution
{
public:
void duplicateZeros(vector<int>& arr)
{
//1.先找到最后一个复写的数
int cur = 0, dest = -1, n = arr.size();
while (cur < n)
{
if (arr[cur]) dest++;
else dest += 2;
if (dest >= n - 1) break;//dest越界就跳出循环,=是判断当dest走到n的位置特殊情况
cur++;
}
//2.处理边界情况
if (dest == n)
{
arr[n - 1] = 0;
cur--;
dest -= 2;
}
//从后往前复写
while (cur >= 0)
{
if (arr[cur]) arr[dest--] = arr[cur--];
else
{
arr[dest--] = 0;
arr[dest--] = 0;
cur--;
}
}
}
};博主笔记(字迹有点丑,请大家见谅):

往期回顾:
《一篇拿下!C++类和对象(下):初始化列表、类型转换、Static、友元、内部类、匿/有名对象及其优化》
结语:本篇博客系统讲解了双指针算法在数组处理中的应用,重点分析了移动零和复写零两道典型题目。针对移动零问题,采用快排思想实现数组划分;复写零问题则通过前后双指针策略完成原地操作。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。