LeetCode 算法:复写零

182 阅读1分钟

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

复写零

原题地址

给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

示例 1:

输入:arr = [1,0,2,3,0,4,5,0]
输出:[1,0,0,2,3,0,0,4]
解释:调用函数后,输入的数组将被修改为:[1,0,0,2,3,0,0,4]

示例 2:

输入:arr = [1,2,3]
输出:[1,2,3]
解释:调用函数后,输入的数组将被修改为:[1,2,3]

提示:

  • 1 <= arr.length <=10410^4
  • 0 <= arr[i] <= 9

思路分析

方法一

  1. 需要在数组原地进行修改,因此需要遍历数组,在遇到 0 的时候给数组中对应的下一个位置插入一个元素 0,并将下标进行 加1 的操作 「为了防止0会继续重复添加」
  2. 在遍历完数组后,可以看到数组中多了几个0,但是题目要求最终的数组不能超过原数组的长度;
  3. 因此需要在初始时记录数组的长度 len,在遍历完成时,使用 splice 截取数组的前 len 项即可。

方法二

  1. 该方法使用粗暴且有效的二次遍历;
  2. 正向遍历数组,遇到 0 时,将该位置以后的数据均向后复制移动一位,j 逆向处理要赋值的数据;
  3. 因为在遍历过程中给每个下标的元素直接赋的值,因此是在数组原地进行修改的。

AC 代码

方法一

/**
 * @param {number[]} arr
 * @return {void} Do not return anything, modify arr in-place instead.
 */
var duplicateZeros = function(arr) {
    const len = arr.length
    for(let i = 0; i < len; i++) {
        if(arr[i] === 0) {
            arr.splice(i, 0, 0)
            i++
        }
    }
    arr.splice(len)
};

结果:

  • 执行结果: 通过
  • 执行用时:80 ms, 在所有 JavaScript 提交中击败了30.12%的用户
  • 内存消耗:43.3 MB, 在所有 JavaScript 提交中击败了56.63%的用户
  • 通过测试用例:30 / 30

方法二

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

结果:

  • 执行结果:通过
  • 执行用时:68 ms, 在所有 JavaScript 提交中击败了81.33%的用户
  • 内存消耗:43.7 MB, 在所有 JavaScript 提交中击败了7.23%的用户
  • 通过测试用例:30 / 30

END