JS算法练习-Day06-移动零

42 阅读3分钟

Day05已经是三天前的事情了,断更了三天,真的是上班强度太累了,我只要不太累,都要坚持每日一题的去坚持,当然我的JavaScript基础回顾还在继续,其实在断更的这几天里,我在学习过程中做了求闰年,九九乘法表,冒泡排序和选择排序,也算是没有间断算法练习了,不说这么多废话了,上题目: 283. 移动零
给定一个数组 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. 从Day05以后,不再写python了,那也是之前学python的时候写的,也就学了个基础语法,现在还是专注前端吧

  2. 我最开始想使用filter + concat来实现的,这个确实能实现,但是这两个方法都会生成新的数组,不满足题目要求了,因为题目明确要求:必须在不复制数组的情况下原地对数组进行操作。

    /**
     * @param {number[]} nums
     * @return {void} Do not return anything, modify nums in-place instead.
     */
    var moveZeroes = function(nums) {
        nums = nums.filter(i => i !== 0).concat(nums.filter(i => i === 0))
    };
    
  3. 我想着用分割字符串,就是出现个0,我就删除他,然后再在末尾追加一个,也肯定能实现,于是就有了下面这个方法,但是这个方法相当于做了两次循环,一个是for..0f,一个是indexOf,这样时间复杂度就是O(n^2)

    /**
     * @param {number[]} nums
     * @return {void} Do not return anything, modify nums in-place instead.
     */
    var moveZeroes = function(nums) {
        for(i of nums) {
            if(i === 0) {
                nums.splice(nums.indexOf(i), 1)
                nums.push(0)
            }
        }
    };
    
  4. 为了降低时间复杂度,我想着观察了一下,好像有以下规律

    • 第一个非零元素,我让他去数组的第一个,那也就是说我把nums[0]和这个元素交换位置
    • 第二个非零元素,我让他去数组的第二个,那也就是说我把nums[1]和这个元素交换位置
    • 第三个......
    • 第四个......
    • 总结,我弄个下标index =0,遇到非零元素换一下,然后++,就能实现,这个我查了一下,叫双指针
    /**
     * @param {number[]} nums
     * @return {void} Do not return anything, modify nums in-place instead.
     */
    var moveZeroes = function(nums) {
    
        let index = 0
        for(let i = 0; i < nums.length; i++) {
            if(nums[i] !== 0) {
                [nums[index], nums[i]] = [nums[i], nums[index]]
                index++
            }
        }
    };
    

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

  • 这个是D老师给的滚雪球的方法,有点冒泡的影子(但Deepseek说不是,他说是插入算法的优化),想知道原理的自己去问Deepseek
var moveZeroes = function(nums) {
    let snowBallSize = 0;
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] === 0) {
            snowBallSize++;  // 遇到零时,"雪球"增大
        } else if (snowBallSize > 0) {
            // 将当前非零元素与雪球最前面的零交换
            nums[i - snowBallSize] = nums[i];
            nums[i] = 0;
        }
    }
};