

双指针算法介绍
在数组或链表处理中,双指针是一种非常高效的技巧。常见的形式主要有两种:对撞指针和快慢指针。
对撞指针
通常用于顺序结构,也叫左右指针。两个指针分别从两端向中间移动,一个从最左端开始,另一个从最右端开始,逐渐逼近。终止条件通常是两指针相遇(left == right)或错开(left > right)。
快慢指针
又称龟兔赛跑算法。基本思想是使用两个移动速度不同的指针在序列上移动。这种方法特别适合处理环形链表或需要检测循环的场景。最常用的实现是在一次循环中,让慢指针每次移动一位,快指针每次移动两位。
01. 移动零
这道题的核心在于【数组分两块】,即根据某种划分方式将数组内容分成左右两部分。利用双指针可以原地完成操作。
题目描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。请注意,必须在原数组上操作,不能拷贝额外的数组。
算法思路
我们可以借鉴快速排序中的分区思想。定义两个指针:
cur:用来扫描整个数组。dest:用来记录非零序列的最后一个位置。
目标是让 [0, dest] 区间内的元素全部是非零元素,而 [dest+1, cur-1] 区间内的元素全是零。
算法流程
- 初始化
cur = 0,dest = -1。初始化为-1是因为刚开始还不知道第一个非零元素在哪里。 - 遍历数组,针对
nums[cur]的值分类处理:- 遇到 0:直接跳过,
cur++。这样0自然落在了dest+1之后的区域。 - 遇到非 0:先将
dest自增,然后交换nums[dest]和nums[cur]。因为dest指向的是当前非零区间的末尾,新遇到的非零数应该紧跟其后。
- 遇到 0:直接跳过,
C++ 代码演示
class Solution {
public:
{
cur = ;
dest = ;
(cur < nums.()) {
(nums[cur]) {
(nums[++dest], nums[cur]);
}
cur++;
}
}
};





