双指针实战:移动零与复写零算法解析
一、移动零
1. 题目描述

2. 核心思路
这道题的核心在于'数组划分'。我们可以把数组看作两个区域:左边是非零元素区,右边是零元素区。
使用两个指针 dest 和 cur 来维护这个状态:
cur:负责扫描整个数组,从左向右遍历。它左边的部分已经处理完毕,右边尚未处理。dest:指向已处理区间中最后一个非零元素的位置。
这样数组就被划分为三个逻辑区间:
[0, dest]:已确认的非零元素。(dest, cur):已确认为零的元素。[cur, n):待处理的元素。
当 cur 移动到数组末尾时,中间区间消失,数组自然满足要求。
具体操作:
- 初始化:
cur指向首元素,dest初始化为-1(表示尚未找到非零元素)。 - 遍历过程:
- 若
nums[cur]为 0:无需交换,直接cur++,扩大中间的零区间。 - 若
nums[cur]非 0:说明需要将其归入左侧非零区。先将dest右移一位,然后交换nums[dest]和nums[cur],最后cur++。
- 若
3. 代码实现
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int dest = -1, cur = 0;
// cur 每轮都会自增,所以不需要单独处理遇到 0 的情况
for (; cur < nums.size(); cur++) {
if (nums[cur]) {
// 遇到非 0 元素时,将其交换到 dest 后一位
(nums[++dest], nums[cur]);
}
}
}
};



