leetcode初级算法题解Javascript - 283. 移动零

124 阅读2分钟

题目: 283. 移动零

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

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

示例 1:

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

题解1:

遍历数组得到数组中非零元素的集合data,dada的长度count即为非零元素的个数; 遍历nums,将nums前count个元素替换为data的元素,剩下位置赋值为0

image.png

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

image.png

题解2:双指针快慢指针

可以从前往后遍历数组,将数组中为0的元素依次替换为非零元素。使用双指针快慢指针解题,设置慢指针i 标识当前元素为0,快指针j 寻找非零元素,保持 j 指针始终在 i 指针后面。

image.png

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let i = 0
    let j = 1
    while(i < nums.length && j < nums.length) {
        if(nums[i] == 0 && nums[j] != 0) {
            nums[i] = nums[j]
            nums[j] = 0
            i++
            j++
        }
        // 指向0元素
        if(nums[i] != 0 ){
            i++
        }
        // j指向非0元素,且始终在i指针后面
        if(nums[j] == 0 || j<= i) {
            j++
        }
    }
};

image.png

优化

i 指针指向已处理好的序列尾部,j 指向待处理的序列头部,当 j 指向非零元素时,交换两个指针指向的元素,i 指针更新向右移动

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

image.png