LeetCode 283.移动零(快慢同向双指针)

发布时间:2026/8/5 11:58:18
LeetCode 283.移动零(快慢同向双指针) class Solution { public void moveZeroes(int[] nums) { // left慢指针标记下一个非0元素应当存放的位置 int left 0; // right快指针从头到尾遍历数组寻找非0元素 for(int right 0; right nums.length; right) { // 找到非0数字 if(nums[right] ! 0){ // 交换left位置与right位置的元素 int temp nums[right] ; nums[right] nums[left]; nums[left] temp; // left位置已经存放好非0元素向后移动等待下一个非0 left ; } } } }一、核心算法思路快慢双指针原地操作数组定义快指针 right遍历整个数组负责寻找所有非 0 元素定义慢指针 left代表下一个非 0 元素需要放置的目标下标每当 right 找到非 0 数字交换 left 与 right 位置的值随后 left 右移right 无论是否找到非 0 元素都会持续向右遍历最终所有非 0 元素全部移至数组左侧0 集中到数组末尾原地修改数组不额外开辟数组空间满足题目要求。实例运行顺序演示测试输入nums [0,1,0,3,12]初始状态left 0rightnums[right]是否非 0操作数组变化left 最终值00❌ 否不交换[0,1,0,3,12]left011✅ 是交换下标 0 和 1[1,0,0,3,12]left120❌ 否不交换[1,0,0,3,12]left133✅ 是交换下标 1 和 3[1,3,0,0,12]left2412✅ 是交换下标 2 和 4[1,3,12,0,0]left3循环结束最终结果[1,3,12,0,0]补充演示【开头为非 0 数字场景】测试输入nums [1,3,0,3,12]初始状态left 0rightnums[right]是否非 0操作数组变化left 最终值01✅ 是交换下标 0 和 0自身交换[1,3,0,3,12]left113✅ 是交换下标 1 和 1自身交换[1,3,0,3,12]left220❌ 否不交换[1,3,0,3,12]left233✅ 是交换下标 2 和 3[1,3,3,0,12]left3412✅ 是交换下标 3 和 4[1,3,3,12,0]left4结论left 与 right 重合时会发生自身交换不会改变数组逻辑正确只是无效运算。二、语法 概念理解困惑点整理left、right 双指针作用区分1) left慢指针只有成功放置一个非 0 元素之后才前进2) right快指针持续不断遍历数组每一个位置。3) 当数组前面是连续非 0 数字时left 与 right 下标相等触发自身交换不会改变数组内容代码逻辑依然正确只是一次无效交换。void 方法特点 不需要 return 返回数值数组为引用类型方法内直接修改原数组。三、踩坑清单误区认为 left right 时必须特殊判断 自身交换不会报错只是无效操作想要优化性能可以增加判断if(left ! right)再执行交换不添加也能通过测试。边界案例考虑不全 输入nums[0]、nums[1]、nums[0,0,0]等极端场景双指针代码均可正常处理。四、高频易混知识点双指针适用场景原地数组元素归类把一类元素放左边、另一类放右边区分快慢双指针一个快走、一个慢走vs 左右对撞双指针本题属于快慢双指针