主题
复盘 · LC 283 移动零(二刷)
题目
- 题号:LeetCode 283
- 名称:移动零(Move Zeroes)
- 难度:Easy
- 链接:leetcode.cn/problems/move-zeroes
- 今日代码:
283-移动零-二刷/index.js
题意
给定数组 nums,把所有 0 原地移到末尾,其余非零元素保持相对顺序不变。
- 必须修改原数组;函数签名多为
void。 - 进阶:尽量少操作次数。
边界:全零、无零、单元素、零与非零交错。
涉及算法
| 标签 | 一句话 |
|---|---|
| 同向双指针 / 读写指针 | 慢指针写下一个非零该放的位置,快指针扫描 |
| 原地交换 | 非零与 slow 交换,零自然沉到后面 |
教程对照:06 · 同向双指针与快慢指针。
首刷复盘(splice 版):2026-07-20 · 283。
评价我的解法
相对 7/20 的反复 splice + push(0),今天直接写出快慢指针交换,和当时「最佳题解」同构——二刷升级成功。
我的代码(摘自 283-移动零-二刷/index.js):
javascript
var moveZeroes = function (nums) {
let slow = 0;
for (let fast = 0; fast < nums.length; fast++) {
if (nums[fast] !== 0) {
const tmp = nums[fast];
nums[fast] = nums[slow];
nums[slow] = tmp;
slow++;
}
}
return nums;
};1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
对在哪:
- O(n) 一次扫描:每个下标常数次读写,没有中间段整体搬移。
- 相对顺序:非零按遇到的次序依次换到前面,相对序保持。
- 与首刷比:从「会过样例」升到「会读写指针模板」。
糙在哪:
- 返回
nums:判题不看返回值;面试说「原地改、无返回」更贴签名。 fast === slow时自交换:正确但多余;可写成「仅当fast !== slow才换」,或先覆写再尾部填 0。
小结:Easy 双指针二刷达标。说明 06 的读写指针已经能默写;今天主菜仍是 Medium 对撞(11/15)。
最佳题解
与今日解同一套路;也可「先写非零再填零」避免无意义自交换:
javascript
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function (nums) {
let slow = 0;
for (let fast = 0; fast < nums.length; fast++) {
if (nums[fast] !== 0) {
nums[slow++] = nums[fast];
}
}
while (slow < nums.length) {
nums[slow++] = 0;
}
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 时间 O(n),空间 O(1)。
- 交换版与填零版都是面试可讲写法;关键口述「慢指针含义」。
关联题目
| 题 | 为何相关 |
|---|---|
| 27. 移除元素 | 同一套读写指针 |
| 26. 删除有序数组中的重复项 | 慢指针写保留位置 |
| 75. 颜色分类 | 原地分区进阶 |
一句话带走
移动零二刷 = 快找非零、慢写位置(交换或覆写);别再靠 splice。
