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

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

示例 1:

输入: nums = [0,1,0,3,12] 输出: [1,3,12,0,0]

示例 2:

输入: nums = [0] 输出: [0]

提示:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

**进阶:**你能尽量减少完成的操作次数吗?


方法思路 要将所有零移动到数组末尾,同时保持非零元素的相对顺序,可以采用双指针法。通过两次遍历实现:

  1. 第一次遍历:使用快慢指针,快指针遍历数组,遇到非零元素时,将其移动到慢指针的位置, 并移动慢指针。这样所有非零元素会被移动到数组前面。
  2. 第二次遍历:将慢指针之后的所有位置填充为零,以确保零元素位于数组末尾。

这种方法保证了时间复杂度为 O(n),且原地操作,无需额外空间。

解决代码

var moveZeroes = function(nums) {
    let left = 0;
    // 将非零元素移到前面
    for (let right = 0; right < nums.length; right++) {
        if (nums[right] !== 0) {
            nums[left] = nums[right];
            left++;
        }
    }
    // 将剩余位置填充零
    for (let i = left; i < nums.length; i++) {
        nums[i] = 0;
    }
};

代码解释

  1. 第一次遍历:快指针 right 遍历数组,当遇到非零元素时,将其赋值给慢指针 left 的位置,并递增 left。这样遍历结束后,所有非零元素都被移动到数组的前面。
  2. 第二次遍历:从慢指针 left 的位置开始,将剩余的位置填充为零,确保所有零元素位于数组末尾。该方法保证了非零元素的相对顺序不变,且原地操作。