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

力扣hot100-206.反转链表-双指针详解

206. 反转链表:双指针详解

题目链接:206. 反转链表


算法思路

链表 / 指针操作 / 原地反转

题目给出一条单链表:

1 -> 2 -> 3 -> 4 -> 5 -> null

要求把每个节点的next指针方向全部反过来,得到:

5 -> 4 -> 3 -> 2 -> 1 -> null

注意:这里不是创建一条新链表,也不是交换节点中的val

真正要做的是:

逐个修改每个节点的 next 指针。

1. 为什么不能直接修改next

假设现在链表是:

1 -> 2 -> 3 -> null

第一次处理节点1时,设:

cur = 1 pre = null

反转当前节点,本来需要写:

cur.next=pre;

也就是:

1.next=null;

如果直接这样做,链表会变成:

1 -> null 2 -> 3 -> null

问题在于:节点1原来通向节点2的指针被覆盖了,而我们还没有保存节点2

于是从1出发,后面的2 -> 3就无法再访问,相当于丢失了未处理的链表。

所以,修改cur.next之前必须先保存原来的下一个节点:

ListNodenext=cur.next;

这是本题最关键的一步。


2. 三个指针分别表示什么

我们使用三个指针:

ListNodepre=null;ListNodecur=head;ListNodenext;

它们的职责是:

指针含义
pre已经反转完成部分的头节点
cur当前正在处理、准备反转的节点
next暂存cur原本的下一个节点,防止后续链表丢失

刚开始时:

pre = null cur = 1

对应的链表状态是:

已反转部分:null 未处理部分:1 -> 2 -> 3 -> 4 -> 5 -> null cur

pre的含义不是“前一个节点”这么简单。更准确地说:

pre 始终指向已经反转完成部分的最前面。

因此,所有节点处理完后,pre就会指向新链表的头节点。


3. 每轮循环固定做三件事

处理cur时,顺序不能乱:

1. 保存 cur 的原后继节点 2. 修改 cur.next,让它指向 pre 3. 移动 pre 和 cur,准备处理下一个节点

代码就是:

ListNodenext=cur.next;cur.next=pre;pre=cur;cur=next;

可以把它记成一句话:

保存后继 -> 反转指向 -> 指针前进

其中第一步必须排在第二步之前;因为一旦执行cur.next = precur原来的后继关系就被覆盖了。


4. 用1 -> 2 -> 3完整推演

初始状态:

null 1 -> 2 -> 3 -> null pre cur

第 1 轮:处理节点 1

第一步,保存节点1原本的下一个节点:

next=cur.next;
next = 2

第二步,反转节点1的指向:

cur.next=pre;
null <- 1 2 -> 3 -> null cur

第三步,移动两个主指针:

pre=cur;cur=next;
null <- 1 2 -> 3 -> null pre cur

节点1已经进入“反转完成部分”,节点2成为下一轮要处理的节点。

第 2 轮:处理节点 2

先保存后继:

next = 3

再反转当前节点的指向:

null <- 1 <- 2 3 -> null cur

移动指针后:

null <- 1 <- 2 3 -> null pre cur

第 3 轮:处理节点 3

先保存后继:

next = null

反转节点3的指向:

null <- 1 <- 2 <- 3 cur

移动指针:

null <- 1 <- 2 <- 3 pre cur = null

此时没有待处理节点,循环结束。

最终:

pre = 3

所以返回pre,得到:

3 -> 2 -> 1 -> null

5. Java 代码完整注释

classSolution{publicListNodereverseList(ListNodehead){// pre 指向已经完成反转部分的头节点。// 开始时还没有节点被反转,因此为 null。ListNodepre=null;// cur 指向当前需要处理、需要反转的节点。ListNodecur=head;// 当 cur 不为 null,说明还有节点未处理。while(cur!=null){// 先保存 cur 原本的下一个节点。// 下一步会覆盖 cur.next;不提前保存,后续链表会丢失。ListNodenext=cur.next;// 让当前节点指向已经反转部分的头节点,// 从而完成当前节点的指针反转。cur.next=pre;// 当前节点已经成为反转完成部分的新头节点。pre=cur;// 继续处理原链表中的下一个节点。cur=next;}// 所有节点都处理完后,pre 就是反转后链表的新头节点。returnpre;}}

6. 为什么返回pre,而不是head

原来的head指向节点1

head | v 1 -> 2 -> 3 -> null

反转之后,节点1会变成尾节点:

3 -> 2 -> 1 -> null ^ head

所以原来的head不再能代表新链表的头节点。

而在每一轮循环中:

pre=cur;

都会让pre指向当前已经反转完成部分的最前面。

当所有节点都处理完时:

已反转完成部分 = 整条链表

因此:

pre 就是反转后链表的新头节点。

7. 边界情况

空链表:

head = null

此时:

cur = null

循环不会执行,直接返回:

pre = null

结果正确。

只有一个节点:

1 -> null

执行一轮后:

1 -> null

节点仍然是它自己,结果正确。


8. 复杂度

假设链表有n个节点。

时间复杂度:

O(n)

每个节点只会被cur处理一次。

额外空间复杂度:

O(1)

只使用了precurnext三个指针变量,没有创建与链表长度相关的额外空间。

一句话记忆:

反转链表时,先用 next 保住后半段,再让 cur 指向 pre,最后让 pre 和 cur 一起前进。
http://www.jsqmd.com/news/1302508/

相关文章:

  • MicroOrm.Dapper.Repositories:提升Dapper开发效率的终极CRUD库详解
  • 2026 年主流发票管理工具排名与深度解析
  • 花都区粤菜餐厅哪家正宗:【锦堂春想】古法粤味 - 17328623207
  • 2026年淮安中短发发型师推荐:三大评估维度与口碑首选解析 - 新闻快传
  • 每天吃透一个AI知识点:爆火的AI Agent,才是真正的「未来AI」
  • 2026年巴基斯坦名义雇主服务费收取全景推荐:探寻十大优质方案
  • 什么是赛默飞 Thermo Fisher原子吸收光谱仪 - 实了个验
  • 实测多款录音神器准确率对比,2026年用了半年我只留下这一个
  • 淮安清江浦区女发型师推荐:2026年熟女烫染三大评估维度与专业人选分析 - 新闻快传
  • 单片机毕设选题推荐:基于 HC-SR04 传感器的智能防撞报警装置设计 基于嵌入式技术的距离分级声光预警系统开发(014201)
  • 2026年浮筑楼板减振垫厂家挑选全指南 选型标准与优质品牌盘点 - 广华节能科技有限公司
  • LinkedHashMap 一些示例、BigDecimal
  • 单片机毕设选题推荐:基于 L9110 驱动的厨房智能通风照明一体机设计 多传感器融合的 STM32 环境智能控制系统设计与实现(014301)
  • 花都区粤菜餐厅哪家适合家庭聚?:【锦堂春想】阖家相宜 - 18002239949
  • Swagger文档验证终极方案:使用Swagger-Tools确保API规范的结构与语义正确性
  • GPT-SoVITS:一分钟打造专属AI语音助手,开启声音克隆新纪元
  • Windows安卓子系统(WSA)免费安装指南:Windows 11运行安卓应用的5个高效方法
  • 会议记录语音实时转文字免费和付费区别大吗2026实测对比后给你明确答案
  • 实测盘点|5款免费AI生成PPT工具!零门槛一键出稿,打工人直接抄作业 - 品牌测评鉴赏家
  • 如何用TradingAgents-CN构建多智能体AI股票分析系统:从零到一的完整实战指南
  • HVI-CIDNet-LOLv1-fp32深度解析:从模型架构到1.9M参数优化
  • 【AI自动化测试实战指南】:20年测试架构师亲授5大落地陷阱与避坑清单
  • 审批移动端-用户绑定微信 服务号消息模版通知(工单审批通知)
  • 大庆存量商铺翻新潮:老门店改头换面,工装设计怎么做才不白花钱 - 产品评测官
  • 孟加拉的海外人力资源外包是什么?
  • 花都区粤菜餐厅哪家食材新鲜:【锦堂春想】食材鲜活 - 17728098551
  • 部署搜索优化源码必看:服务器安全配置、源码防篡改、防爬虫封禁设置
  • 【转帖】四大行到底是哪四家?一文讲清,存钱贷款不踩懵
  • 力扣hot100-234.回文链表-快慢指针与反转详解
  • 电路题目