LeetCode探索(94):1089-复写零

103 阅读1分钟

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

题目

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

注意:请不要在超过该数组长度的位置写入元素。

要求:请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

示例 1:

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

示例 2:

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

提示:

  1. 1 <= arr.length <= 10000
  2. 0 <= arr[i] <= 9

思考

本题难度简单。

首先是读懂题意。我们需要将数组中出现的每个零都复写一遍,并将其余的元素向右平移。要求:请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

我们可以注意到,需要原地修改数组本身!而且返回值数组的长度跟输入数组的长度是一样的

我们可以使用双指针进行解题。用 count 记录数组元素的个数,用 i 标记要插入元素的索引。然后,从索引 i 开始判断是否为0,在原数组的末尾开始修改,如果为0则修改为00;不为0则修改为索引 i 对应的数字。注意判断最开始的索引 i 为0的情况,注意 count 此时是否超过数组的长度。

解答

方法一:双指针

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

复杂度分析:

  • 时间复杂度:O(n),其中 n 为数组 arr 的长度。
  • 空间复杂度:O(1)。

参考