双指针算法实战:移动零与复写零
在掌握了基础语法后,是时候通过经典题目来打磨基本功了。今天我们来深入探讨两个利用双指针技巧解决的原地数组修改问题:LeetCode 的「移动零」和「复写零」。这两道题看似简单,却蕴含着处理边界条件和空间优化的核心思想。
一、移动零
题目描述
给定一个数组 nums,要求将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。注意:必须在不复制数组的情况下原地操作。

原理解析
最直观的想法是新建一个数组存放非零元素,但这违反了原地操作的要求。我们可以使用双指针策略:
- 快指针 (
current):负责遍历整个数组,寻找非零元素。 - 慢指针 (
write):指向当前应该放置非零元素的位置。
当快指针遇到非零数时,将其交换到慢指针位置,然后慢指针前进一步。这样,所有非零元素会被依次前置,剩余位置自然就是 0。
代码实现
void Swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void moveZeroes(int* nums, int numsSize) {
int write = 0;
for (int current = 0; current < numsSize; current++) {
if (nums[current] != 0) {
Swap(&nums[write], &nums[current]);
write++;
}
}
}
这段逻辑提交验证无误,关键在于只遍历一次,时间复杂度为 O(n),空间复杂度为 O(1)。
二、复写零
题目描述
在一个固定长度的整数数组中,将每个出现的 0 重复一遍。如果数组长度不够容纳所有元素,则丢弃后续元素。同样需要原地修改。



