算法56,重排链表

找链表中点:使用快慢双指针(快指针一次走两步,慢指针一次走一步),当快指针到达末尾时,慢指针正好停在中间(奇数个节点在正中间,偶数个节点在前半段末尾)。

后半部分逆序 :将慢指针后面的链表截断,并使用头插法进行逆序反转。

交替合并:将前半段链表和反转后的后半段链表,使用双指针交替一个接一个地拼接起来。

知识点一:快慢指针找中间结

  • 核心操作:慢指针每次走1步,快指针每次走2步。当快指针到达末尾时,慢指针停在前半段最后一个节点。
  • 本题细节 :
    • 奇偶长度处理:奇数个节点时慢指针在正中间,偶数个节点时慢指针在前半段末尾。
    • 循环条件 :必须使用 fast != null && fast.next != null,防止空指针异常。
    • 截断链表 :找到中点后,必须用 slow.next = null 将前后半段链表彻底断开。

知识点二:头插法逆序链表

  • 核心操作:创建虚拟头结点,遍历原链表,将每个节点依次插入到虚拟头结点之后,实现局部反转。
  • 本题细节 :
    • 保存后继 :遍历断链前,必须用 next = cur.next 提前保存下一个节点。
    • 反转基准 :以 slow.next 作为后半段起点进行反转,原 fast 指针此时已失效不可再用。
    • 虚拟头结点 :使用虚拟头结点(如 new ListNode(0))可以省去判断头结点为空的额外逻辑。

知识点三:尾插法合并两个链表

  • 核心操作:使用双指针分别指向两个链表,通过另一个指针(prev)始终指向合并链表的尾部,交替将节点接在尾部。
  • 本题细节 :
    • 长度差异 :前半段链表比后半段长(多1个或0个节点),合并时以前半段为准,需加 if(cur2 != null) 判断后半段是否结束。
    • 指针后移 :接上节点后,必须同步移动 prev 和对应的 cur 指针。
    • 虚拟头结点 :同样使用虚拟头结点简化合并逻辑,最后无需返回(原题要求 void)。

附:重排链表核心代码骨架

复制代码
// 1. 找中间结点
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
    slow = slow.next;
    fast = fast.next.next;
}

// 2. 头插法逆序后半段
ListNode head2 = new ListNode(0);
ListNode cur = slow.next;
slow.next = null; // 断开链表
while (cur != null) {
    ListNode next = cur.next;
    cur.next = head2.next;
    head2.next = cur;
    cur = next;
}

// 3. 尾插法交替合并
ListNode cur1 = head, cur2 = head2.next;
ListNode ret = new ListNode(0);
ListNode prev = ret;
while (cur1 != null) {
    prev.next = cur1; // 先接前半段
    prev = cur1;
    cur1 = cur1.next;
    if (cur2 != null) { // 再接后半段
        prev.next = cur2;
        prev = cur2;
        cur2 = cur2.next;
    }
}
相关推荐
qq_452396232 小时前
第四篇:《索引原理与实战:B-tree、Hash、GIN、GiST、BRIN》
算法·哈希算法·gin
西索斯coding3 小时前
Qwen3-Max 与 Qwen-Plus:60 个真实修复任务评测方案
大数据·网络·算法·ai
INGNIGHT3 小时前
440 · 背包问题(三)(无限次数)
算法·leetcode·动态规划
suhan3 小时前
【数据结构】七、查找:1.查找的概念、线性结构查找(顺序、折半(二分)、插值、稠密、分块、倒排)
数据结构·算法·排序算法
极客 - L U3 小时前
卡尔曼滤波从零到精通
c语言·数据结构·单片机·嵌入式硬件·mcu
killerbasd4 小时前
总结 10.26
算法
深圳安锐科技有限公司4 小时前
从成像尺度到亚像素解算:变焦视觉位移监测如何让远近断面都稳
图像处理·人工智能·深度学习·算法·计算机视觉·系统架构·结构健康监测
一只旭宝4 小时前
回调函数(Callback)
linux·服务器·算法