LeetCode 283. 移动零

题目描述

283. 移动零

image-20230304223011804

思路分析

解法一:覆盖补零(推荐)

核心思路

  • 使用快慢双指针,slow 指向下一个非零元素应填入的位置,fast 遍历整个数组
  • fast 遇到非零元素时,将其写入 nums[slow],然后 slow++
  • 第一次遍历结束后,[0, slow) 区间已填满所有非零元素
  • 第二次遍历将 [slow, n) 区间全部置 0
  • 与 27 题(移除元素)类比:移动零本质是”移除零元素后,用 0 补全末尾”
  • 优点:非零元素只写入一次,写操作次数最少,无多余交换


复杂度分析

  • 时间复杂度:O(n),其中 n 为数组长度,遍历数组两次
  • 空间复杂度:O(1),原地操作,仅使用常数额外空间
class Solution {
    public void moveZeroes(int[] nums) {
        // slow 指向下一个非零元素应填入的位置
        int slow = 0;
        // 快指针遍历数组,将非零元素依次覆写到前面
        for (int fast = 0; fast < nums.length; fast++) {
            if (nums[fast] != 0) {
                nums[slow] = nums[fast];
                slow++;
            }
        }
        // slow 之后的位置全部补零
        while (slow < nums.length) {
            nums[slow] = 0;
            slow++;
        }
    }
}
func moveZeroes(nums []int) {
    // slow 指向下一个非零元素应填入的位置
    slow := 0
    // 快指针遍历,将非零元素依次覆写到前面
    for fast := 0; fast < len(nums); fast++ {
        if nums[fast] != 0 {
            nums[slow] = nums[fast]
            slow++
        }
    }
    // slow 之后的位置全部补零
    for slow < len(nums) {
        nums[slow] = 0
        slow++
    }
}

解法二:交换法

核心思路

  • slow 指向已处理区间的末尾,fast 扫描整个数组
  • fast 遇到非零元素时,将 nums[slow]nums[fast] 交换,slow++
  • 交换后 [0, slow) 区间始终是非零元素,零自然沉底
  • 相比解法一多了交换操作(每次将 0 和非零元素互换),但代码更简洁


复杂度分析

  • 时间复杂度:O(n),其中 n 为数组长度,仅需一次遍历
  • 空间复杂度:O(1),原地操作,仅使用常数额外空间
class Solution {
    public void moveZeroes(int[] nums) {
        // slow 指向已处理非零区间的下一位
        int slow = 0;
        for (int fast = 0; fast < nums.length; fast++) {
            if (nums[fast] != 0) {
                // 将非零元素交换到 slow 位置
                int temp = nums[slow];
                nums[slow] = nums[fast];
                nums[fast] = temp;
                slow++;
            }
        }
    }
}
func moveZeroes(nums []int) {
    // slow 指向已处理非零区间的下一位
    slow := 0
    for fast := 0; fast < len(nums); fast++ {
        if nums[fast] != 0 {
            // 将非零元素交换到 slow 位置
            nums[slow], nums[fast] = nums[fast], nums[slow]
            slow++
        }
    }
}

相似题目

题目 难度 考察点
27. 移除元素 简单 双指针
26. 删除有序数组中的重复项 简单 双指针
80. 删除有序数组中的重复项 II 中等 双指针
75. 颜色分类 中等 双指针
905. 按奇偶排序数组 简单 双指针
922. 按奇偶排序数组 II 简单 双指针
88. 合并两个有序数组 简单 双指针
977. 有序数组的平方 简单 双指针
本文作者:
本文链接: https://hgnulb.github.io/blog/2026/93474974
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!