[ 力扣283 ] 移动零(js数组splice方法极简实现) | 刷题打卡

404 阅读2分钟

题目名称:移动零

题目地址:leetcode-cn.com/problems/mo…

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

示例:

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

说明:

必须在原数组上操作,不能拷贝额外的数组。 尽量减少操作次数。

解法

一、中规中矩双指针

  • 快慢双指针,j 是慢指针,i是快指针,i跟随遍历,如果遇到非0
    • i和j相等就j++(同时i在循环中也加1了)
    • i和j不相等就交换位置
/**
 * @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) {
        j++
      } else {
        // 遇到非0元素了,要和0元素交换位置
        [nums[j++], nums[i]] = [nums[i], nums[j]]
      }
    }
  }
}

原理:

二、js数组的splice方法自身操作

  • 不要手里拿着锤子,就看什么都是钉子,双指针虽好,但JavaScript本身遍历也不错
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes1 = function (nums) {
  let count = 0
  for (let i = 0; i < nums.length - count; i++) {
    if (nums[i] === 0) {
      nums.push(nums.splice(i, 1)[0])
      count++
      i--
    }
  }
}
  • 原理很简单,从前往后遍历,只要遇到0,就splice删除并push到最后
    • 每次执行一遍上述操作,需要遍历的数组长度-1
    • 采用count计数,可以减少无效判断

三、双指针进化

  • j是慢指针,i是快指针
    • 从前向后遍历,如果nums[i]不为0,那么j所在位置设置为i值,i和j都加1
    • 否则只有i加1,这样能保证j所处位置都是顺序排列的非零值
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes2 = function (nums) {
  let len = nums.length
  let j = 0
  for (let i = 0; i < len; i++) {
    if (nums[i]) {
      nums[j++] = nums[i]
    }
  }
  for (let i = j; i < len; i++) {
    nums[i] = 0
  }
  return nums
};

测试用例

// 测试用例
let test = [0, 1, 0, 3, 12]
let test1 = [0, 0, 1]

console.time('执行用时');
console.log(moveZeroes(test));
console.log(moveZeroes1(test));
console.log(moveZeroes2(test));
console.timeEnd('执行用时');

总结

  • 数组的 splice 方法可以删除指定位置元素
    • nums.push(nums.splice(i, 1)[0])可以同时进行,不会冲突

说明

  1. 本题解已同步leetcode-js-simple/08.[ 283 ] 移动零,可以复制代码进行调试。
  2. 总结出了一套亲测有效的前端无痛刷题项目,有助于算法小白平稳入门,详见leetcode-js-roadmap,希望对从零开始刷题的前端小伙伴们带来帮助~

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情