链表篇(五)——链表中间结点

目录

一、题目本质

二、解法

三、复杂度分析

四、变形训练

变体1:返回第一个中间结点

变体2:三分之一位置

变体3:配合断链,用于归并排序找中点

五、自检


876. 链表的中间结点 - 力扣(LeetCode)

一、题目本质

核心模型快慢指针速度差------快指针速度是慢指针的 2 倍,快指针到末尾时,慢指针刚好在中间。

这是快慢指针三大应用之一(定差距、速度差、追及判环)。

二、解法

cpp 复制代码
   ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode dummy(0, head);
    stack<ListNode*> st;
    
    ListNode* p = &dummy;
    while (p) {
        st.push(p);
        p = p->next;
    }
    
    // 弹出 n 个,栈顶就是待删结点的前驱
    for (int i = 0; i < n; i++) st.pop();
    ListNode* prev = st.top();
    
    ListNode* del = prev->next;
    prev->next = prev->next->next;
    delete del;
    
    return dummy.next;
}

核心不变量 :任意时刻,slow 走过的步数 = fast 走过步数的一半。

证明:

  • 初始:slow 走 0 步,fast 走 0 步,0 = 0/2 ✓

  • 每轮:slow 走 1 步,fast 走 2 步,比例始终 1:2

当 fast 到末尾(走了 n 步),slow 刚好走了 n/2 步,即中间位置。

按照题目要求,返回第二个中间节点。

cpp 复制代码
初始:
1 → 2 → 3 → 4 → 5 → 6
↑
slow, fast

第 1 轮:slow=2, fast=3
第 2 轮:slow=3, fast=5
第 3 轮:slow=4, fast=null

slow 停在 4,正是第二个中间结点 ✓

三、复杂度分析

每个结点至多被 fast 访问一次。

四、变形训练

变体1:返回第一个中间结点

只需让 fast 起步就领先一步(即相当于让slow少走一步)

cpp 复制代码
ListNode* fast = head->next;  // 起手就领先

变体2:三分之一位置

快指针速度改为慢指针的 3 倍。

cpp 复制代码
ListNode* oneThirdNode(ListNode* head) {
    ListNode* slow = head;
    ListNode* fast = head;
    
    while (fast && fast->next && fast->next->next) {
        slow = slow->next;
        fast = fast->next->next->next;  // 3 倍速
    }
    return slow;  // 停在约 1/3 处
}

变体3:配合断链,用于归并排序找中点

cpp 复制代码
ListNode* getMidAndCut(ListNode* head) {
    if (!head || !head->next) return head;
    
    ListNode* slow = head;
    ListNode* fast = head->next;  // 找第一个中点
    ListNode* prev = nullptr;     // 记录 slow 的前驱,用于断链
    
    while (fast && fast->next) {
        prev = slow;
        slow = slow->next;
        fast = fast->next->next;
    }
    
    // 断链
    if (prev) prev->next = nullptr;
    return slow;
}

五、自检

  • 能闭眼写出返回第二个中点的版本

  • 能改成返回第一个中点(fast=head->next)

  • 能解释循环条件是 fast && fast->next

  • 知道怎么改成 1/3 位置

  • 能写出带断链的版本(配合归并排序)

相关推荐
JieE21211 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack2019 小时前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树20 小时前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术2 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦2 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050732 天前
(一)小红的数组操作
算法·编程语言
怕浪猫2 天前
Electron 系列文章封面图
算法·架构·前端框架