【算法】数组:移动零

90 阅读1分钟

题目:移动零

leetcode链接:初级算法 - 移动零

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

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

理解:

1、有一个既定数组,数组内元素应该至少有一个数字0

2、将所有0元素移动至末尾

思路:

1、将原数组所有数字0移除,然后统计出0的个数,之后在元素组末尾补上相应位数的0

2、使用双指针进行替换

3、变量替换

误区:

起初想过直接对原数组降序排,结果发现虽然0都在末尾,但是却打乱了非0元素在数组的顺序,导致一些测试实例无法通过

题解:

方案一、剔除数组内的0元素,然后在数组末尾相应位数补0

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

    return nums
};

image.png

方案二、双指针

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var swap = function(nums, left, right) {
    let temp = nums[left];
    nums[left] = nums[right];
    nums[right] = temp;
}

var moveZeroes = function(nums) {
    let len = nums.length, left = 0, right = 0;
    while (right < len) {
        if (nums[right]) {
            swap(nums, left, right);
            left++;
        }
        right++;
    }
    return nums
};

image.png

方案三、

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

image.png

方案四:

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

image.png

总结:

本篇对数组移动零的问题提供了几种解法,其中方案一时间复杂度太差了,远慢于其它几种解法,相比之下还是其它几种解法在时间复杂度上更好些,综合下来还是双指针的方式更好些。