[路飞]_leetcode-283-移动零

1,655 阅读2分钟

「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战

[题目地址] [B站地址]

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

示例:

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

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

sort 排序

解题思路

这里我们首先可以想到借助 sort 来进行排序,a,b 总共有如下 4 种情况:

  1. a,b 都是 0
  2. a,b 都是 非0
  3. a0b非0
  4. a非0``,b0第 1,2 种情况,我们可以保持它们之前的相对位置,减少操作次数, 第 3,4 中则要保证 非00` 的前面。

代码实现

var moveZeroes = function (nums) {
  nums.sort((a, b) => {
    // 如果两个元素都是 非0 或者都是 0,保持相对位置不变,减小操作次数
    if ((a && b) || (a===0 && b===0)) return 0
    // 如果前面是 0 后面是 非0,返回 1,保证 非0 在前,0 在后
    if (a===0 && b) return 1
    // 如果前面是 非0 后面是 0,返回 -1,保证 非0 在前,0 在后
    return -1
  })
}

交换位置

解题思路

本题我们还可以通过双指针交换元素方法解题。
定义指针 l 指向 0r 指向 非0 元素。
l 指向值为 0 的元素,r 指向值为 非0 的元素的时候,判断 l<r && r<len,如果条件成立,则此时找到了一组 0 前 非0 后 的情况,交换两个元素位置。
lr 继续向后查找,直到处理完输入数组,就完成了移动所有 0 到数组末尾的操作。

代码实现

var moveZeroes = function (nums) {
  const len = nums.length
  // l 指向 0,r 指向 非0
  let l = 0,
    r = 0
  // r 指针扫描整个数组
  while (r < len) {
    // l 向后找到为 0 的元素
    while (l < len && nums[l] !== 0) l++
    // r 向后找到 非0 的元素
    while (r < len && nums[r] === 0) r++
    // 如果当前 l<r(即 0 前 非0 后),并且 r 合法,交换两元素位置
    if (l < r && r < len) {
      ;[nums[l], nums[r]] = [nums[r], nums[l]]
    }
    // 向后移动 r 查找新的 非0 元素
    r++
  }
}

至此我们就完成了 leetcode-283-移动零

如有任何问题或建议,欢迎留言讨论!👏🏻👏🏻👏🏻