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

目录

一、题目本质

二、解法

三、复杂度分析

四、变形训练

变体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 位置

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

相关推荐
程序 代码狂人1 分钟前
经典 SQL 面试题:连续登录问题的两种经典解法
java·开发语言·算法
大熊背5 分钟前
一种数码相机快速自动曝光控制方法解读
算法·计算机视觉·自动曝光·快速收敛
程序猿阿森1 小时前
深入解析 NLI:RAG 与大模型防幻觉的“最后一道防线”
前端·人工智能·算法
ss2731 小时前
AI时代首先数据库-PostgreSQL实战笔记 | 18 PostgreSQL基本索引原理与创建
数据库·笔记·postgresql
而后笑面对2 小时前
浅尝贝叶斯估计
人工智能·算法·机器学习
qq_284274052 小时前
电气控制笔记:常用低压电器符号原理与异步电动机点动、自锁、多地控制电路(含考点)
笔记·学习·自动化·制造
坤坤子吖2 小时前
Linux 线程同步与互斥——条件变量与线程同步
linux·开发语言·c++·笔记·学习
乐橙开放平台3 小时前
不用换摄像头,如何用乐橙把海康、大华、宇视统一到一个界面
笔记·物联网·自动化·音视频·智能家居
u0111026753 小时前
图片生成任务的日志记录与敏感信息取舍
前端·图像处理·算法·ai作画