引言
常见的双指针有两种形式,一种是对撞指针,一种是快慢指针。
对撞指针:一般用于顺序结构中,也称左右指针。
- 对撞指针从两端向中间移动。一个指针从最左端开始,另一个从最右端开始,然后逐渐往中间逼近。
- 对撞指针的终止条件一般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环),也就是:
- left == right(两个指针指向同一个位置)
- left > right(两个指针错开)
快慢指针:又称为龟兔赛跑算法,其基本思想就是使用两个移动速度不同的指针在数组或链表等序列结构上移动。如果我们要研究的问题出现循环往复的情况时,均可考虑使用快慢指针的思想。
- 在一次循环中,每次让慢的指针向后移动一位,而快的指针往后移动两位,实现一快一慢。
注意:这里的指针并不是 C 语言中学的 int*、char*的指针(地址),而是用变量记录数组下标(指针),变量++或--相当于指向指针的移动。
【283.移动零】
1、题目描述
2、实现核心及思路
解题思路
这里对撞指针(左右指针)的方案肯定是行不通的,因为题目要求移动 0 元素的同时还要保证非零元素的相对顺序。所以,我们采用两个指针都从数组的左端出发,把非零的元素依次找到放在前面,最后剩下 0 自然就排在数组后面了。
- 刚开始让一个指针cur 先指向数组的第一个元素,另一个指针 dest 初始化为 -1。cur 用来找非零元素,dest 用来确定 cur 之前的 0 元素。
- 当 cur 指向的元素为零则 cur++,继续向后找非零元素来将前面的 0 交换到后面;
- 当 cur 指向的元素不为 0,则让 dest 向前移动一位(dest++),因为此时 cur 之前的元素要么全为 0,要么 dest 和 cur 指向同一个元素。然后,交换 cur 和 dest 指向的元素,cur 继续向后移动(cur++)。
- 结束条件:当 cur 走到数组尾部的时候意味着所有非零元素都找到了,结束。
代码实现
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int size = nums.size();
// 定义双指针
int dest = -1;
int cur = 0; // 指向数组第一个元素
while (cur < size) {
// 找到非零元素
if (nums[cur] != ) {
dest++;
(nums[dest], nums[cur]);
}
cur++;
}
}
};


