LeetCode热题100——283.移动零

62 阅读2分钟

题目描述

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

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

 

示例:

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

 

提示:

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

题解

双指针

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

    }
};

本题我们采用双指针进行求解

设置i,j两个指针,i指针用于for循环中跟踪数组元素,寻找非零的元素,j指针指向下一个非0元素应该放置的位置

算法通过一次遍历,两重判断实现

  1. 遇到非零元素 (nums[i] !== 0)
  • 如果 i = j 元素已经在正确位置(前面没有零),j 递增i 递增。

  • 如果 i > j 找到一个非零元素需要向前移动。

    • 赋值:nums[i] 复制到 nums[j] 的位置(完成了元素的移动)。
    • 归零:nums[i] 的原位置设为 0(为数组末尾准备 0)。
    • j 递增: 非零序列长度增加,j 向前移动一位。
  1. 遇到元素 (nums[i] === 0)
  • j 保持不动。 i 继续向前。
  • 这使得 j 停留在当前 0 的位置,而 i 继续前进寻找第一个非零元素来覆盖它。

时间、空间复杂度

时间复杂度:O(N)

快指针 i 只遍历数组一次。尽管有 if 语句和赋值操作,但总的操作次数与数组长度 N 成线性关系。

空间复杂度:O(1)

算法只使用了固定数量的额外变量(ij),没有创建新数组,因此是原地操作