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

链表反转中最常用的方法————三指针法

🎯 三指针法:链表反转的“瑞士军刀”

三指针法是解决单向链表反转问题的标准解法,无论是:

  • 反转整个链表
  • 反转部分链表(如第 m 到 n 个节点)
  • K 个一组反转链表

它都适用,且逻辑清晰、不易出错。


🔧 核心思想

我们用 三个指针 来协作完成反转:

指针含义
prev已经反转部分的头节点(初始为 null
curr当前正在处理的节点
next用于保存 curr 的下一个节点,防止“断链”

🔄 目标:让每个 currnext 指向 prev,然后一起向前推进。


📈 动态过程图解(以反转前 3 个节点为例)

原始链表:

p -> A -> B -> C -> D -> ...↑curr

我们想从 A 开始反转 k=3 个节点。

初始化:
ListNode prev = null;
ListNode curr = p.next;  // 即 A

此时:

prev = null
curr = A -> B -> C -> ...

🔁 循环执行 k 次:每次做 3 步操作

✅ 第 1 步:保存下一个节点
ListNode next = curr.next;

防止 curr.next 被修改后找不到后续节点。

prev = null
curr = A    next = B↓B -> C -> ...

✅ 第 2 步:反转当前节点的指针
curr.next = prev;

A 指向 prev(即 null),完成第一个节点的反转。

prev = null <- A    next = B↑curr

✅ 第 3 步:三个指针整体前移
prev = curr;  // prev 移到 A
curr = next;  // curr 移到 B

现在:

prev = A <- A    curr = B -> C -> ...↑已反转部分

🔁 继续第二轮(处理 B)

next = curr.next;     // next = C
curr.next = prev;     // B -> A
prev = curr;          // prev = B
curr = next;          // curr = C

结果:

null <- A <- B    C -> ...↑    ↑prev  curr

🔁 第三轮(处理 C)

next = curr.next;     // next = D
curr.next = prev;     // C -> B
prev = curr;          // prev = C
curr = next;          // curr = D

结果:

null <- A <- B <- C    D -> ...↑    ↑prev  curr

✅ 反转完成!

此时:

  • prev 指向新的头节点(原来的第 k 个节点,即 C
  • curr 指向下一组的开始(即 D
  • 原来的第一个节点 A 现在是尾节点

🔗 最后连接前后

// 找到原段的尾节点(即反转前的头,现在是 p.next)
ListNode tail = p.next;// 尾节点指向下一组开头
tail.next = curr;  // A.next = D// p 指向新的头(即 prev)
p.next = prev;     // p -> C -> B -> A -> D -> ...

最终结构:

p -> C -> B -> A -> D -> ...

完美完成 k=3 的反转!


✅ 完整 Java 代码模板

public ListNode reverseKGroup(ListNode head, int k) {ListNode dummy = new ListNode(-1);dummy.next = head;ListNode p = dummy;while (p.next != null) {// 检查后面是否有 k 个节点ListNode curr = p.next;for (int i = 0; i < k; i++) {if (curr == null) return dummy.next;curr = curr.next;}// 开始反转 k 个节点ListNode prev = null;curr = p.next;for (int i = 0; i < k; i++) {ListNode next = curr.next;curr.next = prev;prev = curr;curr = next;}// 连接反转后的部分ListNode tail = p.next;  // 原来的头,现在的尾tail.next = curr;        // 指向下一段p.next = prev;           // p 指向新的头// p 移动到新尾部(即 tail)p = tail;}return dummy.next;
}

✅ 三指针法的优点

优点说明
🧠 逻辑清晰每次只关注一个节点,逐步推进
🛡️ 安全可靠不会断链,不会自环
🔄 通用性强适用于各种反转场景
📉 时间复杂度 O(k)空间复杂度 O(1)

❗ 常见错误提醒

  • ❌ 忘记保存 next → 断链,丢失后续节点
  • ❌ 顺序写错:先改 curr.next 再保存 next
  • ❌ prev 初始不是 null → 反转后成环
  • ❌ 忘记最后连接 tail.next = curr

 

🎁 小技巧:记住口诀

“一保存,二反转,三前进”

1. 保存 next
2. 反转 curr.next = prev
3. prev = curr; curr = next;
http://www.lryc.cn/news/603210.html

相关文章:

  • PHP云原生架构:容器化、Kubernetes与Serverless实践
  • redis【1】
  • 小程序视频播放,与父视图一致等样式设置
  • zama test
  • 百元级工业级核心板:明远智睿×瑞萨V2H,开启AIoT开发新纪元
  • PDF转Word免费工具!批量处理PDF压缩,合并, OCR识别, 去水印, 签名等全功能详解
  • 数据结构之时间复杂度
  • 前端css 的固定布局,流式布局,弹性布局,自适应布局,响应式布局
  • ZKmall开源商城中台架构实践:API 网关与服务治理如何撑起电商技术骨架
  • 在 PolkaVM 上用 Rust 实现 ERC20 合约的全流程开发指南
  • 接口自动化测试pytest框架
  • c++-list
  • 【VOS虚拟操作系统】未来之窗打包工具在前端资源优化中的应用与优势分析——仙盟创梦IDE
  • Redis内存使用耗尽情况分析
  • 40+个常用的Linux指令——下
  • 艾利特机器人:光伏机器人如何重塑清洁能源制造新格局
  • 【CDH】CDH环境中升级ZooKeeper的实战记录
  • 基于KMeans、AgglomerativeClustering、DBSCAN、PCA的聚类分析的区域经济差异研究
  • 【Linux知识】Linux Shell 脚本中的 `set -ex` 命令深度解析
  • 复现cacti的RCE(CVE-2022-46169)
  • Go 客户端玩转 ES|QL API 直连与 Mapping Helpers 实战详解
  • upload-labs靶场通关(1-12)
  • 服务器之光:Nginx--反向代理模块详解及演练
  • 图论:Bellman_ford算法
  • 《汇编语言:基于X86处理器》第10章 结构和宏(3)
  • 【WRF-Chem 实例1】namelist.input 详解- 模拟CO2
  • 鸿蒙Harmony-自定义List组件,解决List组件手势滑动点击卡住问题
  • 【图像噪点消除】——图像预处理(OpenCV)
  • 创建型设计模式-工厂方法模式和抽象工厂方法模式
  • 社区老人健康信息管理系统|基于springboot社区老人健康信息管理系统设计与实现(源码+数据库+文档)