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

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

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

  • 反转整个链表
  • 反转部分链表(如第 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 代码模板

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;
相关推荐
我的xiaodoujiao1 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 38--Allure 测试报告
python·学习·测试工具·pytest
好奇龙猫7 小时前
【AI学习-comfyUI学习-第三十节-第三十一节-FLUX-SD放大工作流+FLUX图生图工作流-各个部分学习】
人工智能·学习
Boilermaker19927 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
saoys7 小时前
Opencv 学习笔记:图像掩膜操作(精准提取指定区域像素)
笔记·opencv·学习
Cherry的跨界思维7 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
alonewolf_998 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
一嘴一个橘子8 小时前
spring-aop 的 基础使用(啥是增强类、切点、切面)- 2
java
sheji34168 小时前
【开题答辩全过程】以 中医药文化科普系统为例,包含答辩的问题和答案
java
电子小白1238 小时前
第13期PCB layout工程师初级培训-1-EDA软件的通用设置
笔记·嵌入式硬件·学习·pcb·layout
恋爱绝缘体18 小时前
2020重学C++重构你的C++知识体系
java·开发语言·c++·算法·junit