You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数组移零功能:JavaScript实现代码在特定测试用例下的异常问题

数组移零代码的问题分析与修复

问题现象

原代码在处理[0,0,1]这类包含连续0的数组时,返回结果为[0,1,0],不符合将所有0移到末尾的要求,但处理[0,1,0,3,12]这类非连续0的数组时能正常运行。

问题原因

原代码通过for循环从前往后遍历数组,遇到0时执行splice(i,1)删除当前元素,再用push(0)把0放到数组末尾。但splice会直接修改数组结构:删除元素后,后续元素会向前移位填补空缺,而循环的i会继续自增,导致跳过了移位到当前i位置的新元素。

以[0,0,1]为例:

  1. 第一次循环i=0,删除索引0的0,数组变为[0,1],push 0后变成[0,1,0];
  2. 循环i自增到1,此时nums[1]是1,不触发处理;
  3. 循环i自增到2,nums[2]是0,删除后数组变为[0,1],push 0后回到[0,1,0],循环结束。
    整个过程中,原本索引1的0被跳过,没有被移到末尾。

修复方案

方案一:调整索引避免跳过元素

当删除元素后,让i自减一次,抵消循环的自增操作,确保下一次循环能检查到移位过来的元素:

var moveZeroes = function(nums) {
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] === 0) {
      nums.splice(i, 1);
      nums.push(0);
      i--; // 回退索引,避免跳过移位后的元素
    }
  }
  return nums;
};

方案二:双指针法(更高效)

避免频繁使用splice(数组删除操作时间复杂度较高),用快慢指针分离非零元素和零元素,最后统一填充0:

var moveZeroes = function(nums) {
  let slow = 0;
  // 将所有非零元素移到数组前半部分
  for (let fast = 0; fast < nums.length; fast++) {
    if (nums[fast] !== 0) {
      nums[slow] = nums[fast];
      slow++;
    }
  }
  // 从slow位置开始,将剩余位置填充为0
  for (let i = slow; i < nums.length; i++) {
    nums[i] = 0;
  }
  return nums;
};

该方法时间复杂度为O(n),空间复杂度为O(1),在处理大数组时性能更优。


内容的提问来源于stack exchange,提问作者coderobsessed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 03:22:55