

双指针算法介绍
双指针是处理数组和链表问题的利器,常见形式主要有两种:对撞指针和快慢指针。
对撞指针
对撞指针通常用于顺序结构,也叫左右指针。两个指针分别从序列的两端向中间移动,一个从左端开始,另一个从右端开始,逐渐逼近。终止条件通常是两指针相遇(left == right)或错开(left > right)。
快慢指针
又称龟兔赛跑算法,核心思想是在序列上以不同速度移动两个指针。这种方法在处理环形链表、检测循环或需要分区时非常有效。最经典的实现是一次循环中,慢指针每次移动一位,快指针每次移动两位。
01. 移动零
这道题的核心在于将非零元素移到前面,同时保持相对顺序。这其实是一种典型的【数组划分】问题,利用双指针可以将数组分为两部分处理。
题目描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。请注意,必须在原数组上操作,不能拷贝额外的数组。
算法思路
我们可以用 cur 指针扫描整个数组,用 dest 指针记录非零序列的最后一个位置。目标是让 [0, dest] 区间内全是非零元素,[dest+1, cur-1] 区间内全是零。
具体流程如下:
- 初始化
cur = 0用于遍历,dest = -1指向非零元素区间的末尾。初始化为 -1 是因为刚开始我们不知道第一个非零元素在哪里。 - 遍历过程中,如果当前元素
nums[cur]为 0,直接跳过,因为我们的目标就是让这部分区域最终变成 0。 - 如果
nums[cur]不为 0,说明找到了一个新的非零元素。此时先将dest自增 1,然后交换nums[dest]和nums[cur]。这样就把新发现的非零元素挪到了正确的位置。
这种写法本质上借用了快速排序中'分区'的思想,只是这里只关注非零元素。
C++ 代码演示
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int cur = 0;
dest = ;
(cur < nums.()) {
(nums[cur]) {
(nums[++dest], nums[cur]);
}
cur++;
}
}
};


