LeetCode283- 移动零 | 算法练习系列

149 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

前言

天天改需求搞的我头皮发麻,来搞一道简单的算法题刷刷,有试试想想没事做做题还是挺爽的,能让脑子灵光点,哈哈哈

题目描述

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

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

 

示例 1:

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

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

示例 2:

输入: nums = [0]

输出: [0]

解题思路

这题需要注意的点如下

  • 首先题目题目说了要在不复制数组的情况下来完成,那我们就不能声明新的数组了
  • 题目中是说把0都移动到数组的尾部,那我们遍历一遍数组就可以了,遇到零就插入到数组的尾部
  • 在插入的同时要把当前位置的0删除掉 代码如下:
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let i =0
    let count = 0 
    while(i<nums.length-count){
         if(nums[i]===0){
            nums.splice(i,1)
            nums.push(0)
            count++
        }else{
            i++
        }
    }
    return nums
};

运行结果:

image.png

优化

上面的解法虽然可以满足题目的要求,但是由于使用了splice()以及push操作,都是很耗时的,下面给出一种更高级的解法,使用双指针。

  • 首先,双指针都指向数组的头部
  • 当指针i指向的数字是非零的时候就那i指向的值和l指向的值进行交换,交换之后l++
  • 这种使用双指针的方法少了从新插入数据的步骤,因为运行速度更快 代码如下:
var moveZeroes = function (nums) {
            let l = 0;
            for (let i = 0; i < nums.length; ++i) {
                if (nums[i] !== 0) {
                    swap(nums, i, l++);
                }
            }
            return nums
        };
        var swap = function (nums, i, j) {
            let temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }

运行结果:

image.png 运行速度明显得到了提升,但其实还有优化的点,那就是目前代码中只要是非零就交换,这样是不合理的,因为存在自己和自己交换的情况,因此代码可以改为如下:

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

运行结果如下:

image.png

总结

代码总是有更优的解决办法,一般都是先做出来再一步步的优化,没有最好的代码,只有更好的代码。