当前位置: 首页 > news >正文

【Hot100|4-LeetCode 283. 移动零 】

预埋link:hot100博客系列写完 ✍️后 会更新灵神题单 的双指针分类题单 。


这段代码是解决 LeetCode 283. 移动零 问题的经典双指针原地解法,核心目标是将数组中的所有 0 移动到末尾,同时保持非零元素的相对顺序,且时间复杂度为 O (n)、空间复杂度为 O (1)(原地操作,不额外开辟数组)。下面从核心思路、代码逐行解析、实例演示、关键细节四个维度详细讲解:

一、问题与核心思路

问题要求

给定一个整数数组 nums,将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。必须在原数组上操作,不能拷贝额外的数组

核心思路:双指针分区

用两个指针(left 和 i)将数组划分为两个区域,实现原地排序:

  1. left 指针:指向下一个非零元素应该放置的位置(即左半区为「已处理的非零元素」)。
  2. i 指针:作为遍历指针,负责扫描整个数组寻找非零元素(即右半区为「待处理的元素」)。
  3. 遍历过程中,一旦找到非零元素,就与 left 指针位置的元素交换,然后 left 指针后移,确保非零元素都聚集在数组左侧,0 自然被挤到右侧。

二、代码逐行解析

java

运行

class Solution {public void moveZeroes(int[] nums) {// 1. 定义left指针,指向非零元素的"边界",初始为0(非零区域为空)int left = 0;// 2. i指针遍历整个数组,寻找非零元素for(int i = 0;i< nums.length;i++){// 3. 当当前元素不为0时,与left位置元素交换,非零区域扩大if(nums[i]!=0){// 交换nums[i]和nums[left]int temp = nums[i];nums[i] = nums[left];nums[left] = temp;// 非零区域右移,left指针后移left++;}}}
}

逐句拆解关键代码

  1. int left = 0

    • left 初始值为 0,代表数组最左侧。此时「非零元素区域」为空,所有元素都处于「待处理区域」。
  2. for(int i = 0;i< nums.length;i++)

    • i 从数组开头遍历到末尾,逐个检查每个元素是否为非零。
  3. if(nums[i]!=0)

    • 核心判断:如果当前遍历到的元素是非零,说明它需要被放到「非零元素区域」的末尾(即 left 指向的位置)。
  4. 元素交换逻辑

    • 用临时变量 temp 交换 nums[i] 和 nums[left]。交换后,nums[left] 成为非零元素,「非零区域」成功扩大。
  5. left++

    • 交换后,left 指针后移一位,指向下一个非零元素的待放置位置

三、实例演示(直观理解过程)

用测试用例 nums = [0, 1, 0, 3, 12] 演示每一步执行过程,清晰看到指针和数组的变化:

遍历步骤inums[i]交换前数组交换后数组left 值变化说明
初始状态--[0, 1, 0, 3, 12]-0left 指向初始位置,非零区域为空
第 1 次循环00[0, 1, 0, 3, 12]不交换保持 0元素为 0,跳过
第 2 次循环11[0, 1, 0, 3, 12][1, 0, 0, 3, 12]从 0→1交换 nums [1] 和 nums [0],非零区域为 [1]
第 3 次循环20[1, 0, 0, 3, 12]不交换保持 1元素为 0,跳过
第 4 次循环33[1, 0, 0, 3, 12][1, 3, 0, 0, 12]从 1→2交换 nums [3] 和 nums [1],非零区域为 [1,3]
第 5 次循环412[1, 3, 0, 0, 12][1, 3, 12, 0, 0]从 2→3交换 nums [4] 和 nums [2],非零区域为 [1,3,12]

最终结果[1, 3, 12, 0, 0],完全符合「非零元素相对顺序不变,0 移到末尾」的要求。

四、关键细节与优化

1. 为什么能保持非零元素的相对顺序?

因为 i 是从左到右顺序遍历的,非零元素会按遍历顺序依次交换到 left 位置,不会改变它们之间的先后关系。比如示例中 1、3、12 的顺序和原始数组一致。

2. 优化点:避免不必要的自交换

当 i == left 时(比如数组开头就是非零元素),交换操作相当于 “自己和自己交换”,没有意义。可以添加一个判断跳过这种情况:

java

运行

if(nums[i]!=0){if(i != left){ // 只有i和left不同时才交换int temp = nums[i];nums[i] = nums[left];nums[left] = temp;}left++;
}

优化后不影响结果,但减少了无意义的赋值操作,效率更优。

3. 复杂度分析

  • 时间复杂度:O (n)。仅遍历数组一次,每个元素最多被交换一次,操作次数与数组长度成正比。
  • 空间复杂度:O (1)。仅用了临时变量 temp,无额外开辟数组等空间,实现原地操作。

五、总结

该解法的核心是双指针分区思想,通过 left 划分非零区域,i 寻找非零元素,用交换实现原地移动。这种思路不仅适用于 “移动零”,还可迁移到类似的「数组分区问题」(如将数组分为奇数和偶数、正数和负数等),是面试中高频考察的基础算法思路。

http://www.dtcms.com/a/581760.html

相关文章:

  • 操作系统拿着文件名查找磁盘文件的全过程
  • 【Hot100 | 6 LeetCode 15. 三数之和】
  • 哪些网站用wordpress建设银行网站总是崩溃
  • c#实现redis的调用与基础类
  • 【深度学习新浪潮】什么是投机解码?大模型推理优化的核心技术解析(含代码实操)
  • Verilog函数function
  • 做电商宠物带哪个网站最好网络营销方法的选择
  • 超融合系统七大核心技术详解
  • Spring Boot 2.7.18(最终 2.x 系列版本)1 - 技术选型:连接池技术选型对比;接口文档技术选型对比
  • 从0到1做一个“字母拼词”Unity小游戏(含源码/GIF)- 单词字母打乱及字母拼词填空逻辑
  • 记一次 Maven 3.8.3 无法下载 HTTP 仓库依赖的排查历程
  • Linux网络初始及网络通信基本原理
  • 免费学软件的自学网站微信app制作
  • Foundation 模态框
  • 赣州深科网站建设深圳商城网站设计电话
  • vllm学习笔记之 PD分离 kv connector
  • 有经验的佛山网站设计东莞华为外包公司
  • 什么是AIGC的创作者?
  • 51单片机基础-GPIO结构详解
  • 织梦系统如何做网站专属头像制作免费
  • 2025高校网络安全管理运维赛--电子取证分析师赛道-决赛WriteUp
  • 蒲公英异地组网路由器全新固件:4G联网、策略路由、日志管理升级
  • 网站建设规划总结做高考题的网站
  • wordpress网站被镜像wordpress邮件功能用不了
  • (111页PPT)智能工厂总体设计方案(附下载方式)
  • sh -c
  • 在若依框架中修改了 Vue 路由的 base 路径后,还需要修改以下几个地方才能正常访问?
  • Spring Boot 注册登录接口进阶(bcrypt密码加密 + Apifox 测试)
  • 重庆住房城乡建设厅官方网站自己做直播网站
  • 服装网站制作网站建设需要的条件