483 字
2 分钟
移动零

题目描述#

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

解题思路#

  1. 双指针策略
    • 使用快慢指针:快指针遍历数组,慢指针标记非零元素位置
    • 快指针遇到非零元素时,与慢指针交换位置
    • 慢指针仅在前移后更新位置
  2. 原位操作
    • 所有操作在输入数组上完成
    • 不创建新数组,减少空间占用
  3. 顺序保持
    • 非零元素交换后保留原始顺序
    • 零元素自然被推向数组末端
  4. 优化交换
    • 避免同位置元素的无谓交换
    • 仅当快慢指针位置不同时执行交换

关键洞察#

  1. 顺序不变性原理
    • 慢指针始终指向首个零位置
    • 非零元素按序与前方零交换,保持相对顺序
  2. 零元素归集
    • 每次交换都将零元素向后移动
    • 遍历结束时零自动聚集在尾部
  3. 边界处理
    • 初始状态慢指针位置正确(首个元素可能是零)
    • 数组全零时无需操作
  4. 高效交换策略
    • 跳过连续非零区域的冗余交换
    • 仅当快指针发现非零且慢指针指向零时交换

复杂度分析#

指标说明
时间复杂度O(n):单次遍历数组,每个元素处理时间 O(1)
空间复杂度O(1):仅使用两个指针,常数额外空间

代码实现#

/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function (nums) {
let a = 0, b = 0;
while (a < nums.length) {
if (nums[a] !== 0) {
nums[b] = nums[a];
b++;
}
a++;
}
while (b < nums.length) {
nums[b++] = 0;
}
};

相似题目#

移动零
https://website-truelovings-projects.vercel.app/posts/algorithms/移动零/
作者
欢迎来到StarSky的网站!
发布于
2025-08-12
许可协议
CC BY-NC-SA 4.0