LeetCode Hot100 - 4. 移动零(Java 题解)

LeetCode Hot100 - 4. 移动零(Java 题解)

题目链接

移动零 - LeetCode

难度

简单

题目描述

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

说明

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

解题思路

本题采用双指针(快慢指针) 解法,是最优解,满足原地修改、时间复杂度 O (n)。

核心思路:

  1. left 指针:指向当前应该放置非零元素的位置
  2. right 指针:遍历数组,寻找非零元素
  3. 遍历过程中,right 每找到一个非零元素,就与 left 位置交换,然后 left 右移;
  4. right 始终右移,直到遍历结束。
  5. 最终所有非零元素都被移动到数组左侧,0 全部在右侧,且非零元素相对顺序不变

复杂度分析

  • 时间复杂度:O(n)

    只遍历一次数组。

  • 空间复杂度:O(1)

    原地修改数组,仅使用常数额外空间。

解题代码(Java)

class Solution {
    public void moveZeroes(int[] nums) {
        // left:存放非零元素的位置
        // right:遍历数组的指针
        int left = 0, right = 0, length = nums.length;
        
        for (int i = 0; i < length; i++) {
            // 遇到非零元素,交换到 left 位置
            if (nums[i] != 0) {
                swap(nums, left, right);
                left++; // 下一个非零元素放在下一位
            }
            right++; // 遍历指针一直前进
        }
    }

    // 交换数组中两个下标的元素
    public void swap(int[] nums, int left, int right) {
        int temp = nums[right];
        nums[right] = nums[left];
        nums[left] = temp;
    }
}

代码解释

  1. 双指针定义

    • left:记录下一个非零元素要存放的下标。
    • right:遍历整个数组,寻找非零元素。
  2. 核心逻辑

    遍历数组,只要找到非零数,就把它交换left 指向的位置,保证非零元素按顺序排列。

  3. swap 方法

    原地交换两个元素,不占用额外数组空间。

  4. 遍历结束

    所有非零元素都在左侧,0 被挤到数组末尾,完成要求。

示例演示

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

执行过程:

  • right=0,值为 0 → 不交换,right++
  • right=1,值为 1 → 交换 left=0 和 right=1 → [1,0,0,3,12],left=1
  • right=2,值为 0 → 不交换,right++
  • right=3,值为 3 → 交换 left=1 和 right=3 → [1,3,0,0,12],left=2
  • right=4,值为 12 → 交换 left=2 和 right=4 → [1,3,12,0,0],left=3

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

易错点

  1. 必须原地修改,不能新建数组。
  2. 要保持非零元素的相对顺序,不能乱序。
  3. 双指针一定要先交换再移动 left,right 全程移动。
  4. 不要用额外空间,否则不是最优解。

总结

本题是经典双指针(快慢指针) 入门题,思路简单、代码优雅,面试常考。

核心思想:用指针标记非零元素位置,遍历交换,实现原地移动零。

posted @ 2026-04-13 21:28  ZhenyangQ  阅读(2)  评论(0)    收藏  举报