【算法】移动零

213 阅读2分钟

难度:简单

题目:

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

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

示例 1:

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

示例 2:

输入: nums = [0]
输出: [0]

提示:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

**进阶:**你能尽量减少完成的操作次数吗?

解题思路:

这个问题可以通过使用双指针技术来解决。我们可以使用两个指针,一个快指针 fast 用于遍历数组,另一个慢指针 slow 用于记录下一个非零元素应该放置的位置。当 fast 遇到非零元素时,就将其交换到 slow 的位置,然后将 slow 向前移动一位。这样可以确保所有的非零元素都放在数组的前面,并且保持了它们的相对顺序。

  1. 初始化两个指针 slowfast,都指向数组的起始位置。
  2. 使用 fast 指针遍历整个数组。
  3. 如果 fast 指针处的元素不为 0,则交换 slowfast 指针处的元素,并将 slow 指针向前移动一位。
  4. 继续遍历直到 fast 指针到达数组的末尾。
  5. 此时 slow 指针之后的所有元素都是 0,不需要再做任何操作。

JavaScript实现:

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
  let slow = 0; // 慢指针,记录下一个非零元素应该放置的位置
  for (let fast = 0; fast < nums.length; fast++) {
    // 当遇到非零元素时
    if (nums[fast] !== 0) {
      // 交换 slow 和 fast 指针处的元素
      [nums[slow], nums[fast]] = [nums[fast], nums[slow]];
      slow++; // 将 slow 指针向前移动一位
    }
  }
  return nums;
};

这种方法只需要一次遍历,时间复杂度为 O(n),并且是原地修改数组,空间复杂度为 O(1)。