💻 [LeetCode Hot100] 移动零🔥双指针法,Java实现!图文详解,小白也能秒懂!
✏️本文对应题目链接:移动零
📌 题目描述
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入:nums = [0, 1, 0, 3, 12]
输出:[1, 3, 12, 0, 0]
🧠 解题思路(图文分解)
❗ 核心难点
如何在原地修改数组,并保持非零元素的相对顺序?
双指针法(黄金思路)✨
关键步骤:
- 初始化指针:
left
指针指向当前非零元素的位置,right
指针用于遍历数组 - 遍历数组:当
right
指针遇到非零元素时,将其移动到left
指针的位置 - 移动指针:每次移动非零元素后,
left
指针右移 - 填充零:遍历结束后,将
left
指针之后的位置全部填充为零
动态过程图解:
初始状态:[0, 1, 0, 3, 12]
- right=0, left=0 → 0跳过
- right=1, left=0 → 移动1到left位置 → [1, 1, 0, 3, 12]
- right=2, left=1 → 0跳过
- right=3, left=1 → 移动3到left位置 → [1, 3, 0, 3, 12]
- right=4, left=2 → 移动12到left位置 → [1, 3, 12, 3, 12]
- 最后填充零 → [1, 3, 12, 0, 0]
🚀 代码实现
class Solution {
public void moveZeroes(int[] nums) {
int left = 0; // 指向当前非零元素的位置
int right = 0; // 用于遍历数组
// 遍历数组,将非零元素移动到前面
while (right < nums.length) {
if (nums[right] != 0) {
nums[left] = nums[right];
left++;
}
right++;
}
// 将剩余位置填充为零
while (left < nums.length) {
nums[left] = 0;
left++;
}
}
}
💡 复杂度分析
- 时间复杂度:O(n) → 只需遍历数组一次
- 空间复杂度:O(1) → 原地修改数组,仅使用常数空间
🌟 总结要点
✅ 双指针核心作用:分离非零元素和零元素
✅ 原地修改:无需额外空间,直接在原数组上操作
✅ 适用场景:数组元素分类、去重、移动等操作
💡 进阶思路:快慢指针优化
如果题目允许不保持非零元素的相对顺序,可以使用快慢指针交换元素,进一步减少操作次数:
int left = 0, right = nums.length - 1;
while (left <= right) {
if (nums[left] == 0) {
swap(nums, left, right);
right--;
} else {
left++;
}
}
⚠️ 注意:此方法会改变非零元素的相对顺序,仅适用于特定场景。
🔥 下期预告:《盛最多水的容器》双指针法的经典应用!