283_移动零(算法思路,优化和复杂度分析)

44 阅读1分钟

题目描述

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

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

示例 1:

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

示例 2:

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

思路

  1. 定义两个指针
    • left 指针:用于指向当前非零元素应该放置的位置。
    • right 指针:用于遍历数组中的每一个元素。
  2. 遍历数组
    • 初始时,leftright 都指向数组的第一个元素。
    • right 指针遍历数组时,如果遇到非零元素,则将该元素与 left 指针所指向的元素交换,并将 left 指针向后移动一位。
    • 如果遇到 0,则只移动 right 指针,left 指针保持不动。
  3. 交换操作
    • right 指针遇到非零元素时,交换 leftright 指针所指向的元素,并将 left 指针向后移动一位。
    • 这样,所有非零元素都会被移动到数组的前面,而 0 会被留在后面。
  4. 结束条件
    • right 指针遍历完整个数组时,所有非零元素都已经被移动到数组的前面,而 0 则被移动到了数组的末尾。

复杂度分析

时间复杂度

仅遍历数组一次, O(N)

空间复杂度

声明1个记录指向零位置O(1)

code

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