[特殊字符] LeetCode 143 重排链表(Reorder List)详解

📌 问题描述

给定一个单链表 L0 → L1 → ... → Ln-1 → Ln ,要求将其重新排列为:

L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → ...

例如:

  • 输入:1 → 2 → 3 → 4 → 5

  • 输出:1 → 5 → 2 → 4 → 3

要求:

  • 不能修改节点的值,只能修改节点本身的指向。

  • 时间复杂度尽量低,空间复杂度 O(1)。

💡 思路分析

这个问题可以分为 三步走

  1. 找到链表中点

    使用快慢指针(fast/slow)。当 fast 每次走两步,slow 每次走一步,当 fast 到尾时,slow 就在中间节点。

  2. 反转链表后半部分

    将中点后的链表整体反转,这样最后一个节点会变成第一个,方便和前半段交替拼接。

  3. 合并两条链表

    交替拼接前半部分和反转后的后半部分,形成目标顺序。

    📝 代码实现(C++)

    cpp 复制代码
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    
     //思路:找到中间节点,分成两条链表,前链表依次插入反转后的链表
    class Solution {
    public:
        ListNode* revise(ListNode *L){//反转
            if(L==nullptr){
                return nullptr;
            }
            if(L->next==nullptr) return L;
            ListNode *head=new ListNode(0);
            head->next=nullptr;
            while(L){
                ListNode *n=L->next;
                L->next=head->next;
                head->next=L;
                L=n;
            }
            return head->next;
        }
        void reorderList(ListNode* head) {
            if(head==nullptr||head->next==nullptr){
                return;
            }
            ListNode *s=head,*f=head;
            while(f&&f->next){//找中间节点
                f=f->next->next;
                s=s->next;
            }
            ListNode *L2=s->next;
            s->next=nullptr;//断开两条链表连接防止互相影响
            ListNode *front=head;
            ListNode *tail=revise(L2);
            while(tail){//插入反转节点
                ListNode*tn=tail->next, *fn=front->next;
                front->next=tail;
                tail->next=fn;
                front=fn;
                tail=tn;
            }
        }
    };

    🔎 关键步骤讲解

  4. 快慢指针找中点

    • slow 每次走一步,fast 每次走两步。

    • 最终 slow 停在中点位置。

  5. 反转链表

cpp 复制代码
ListNode *revise(ListNode *L) {
    ListNode *head=new ListNode(0);
    while(L){
        ListNode *n=L->next;
        L->next=head->next;
        head->next=L;
        L=n;
    }
    return head->next;
}

这样可以把链表 4 → 5 反转成 5 → 4
7. 合并链表

  • 先接前半部分 1 → 2 → 3

  • 然后把反转后的 5 → 4 插入其中

  • 形成最终结果 1 → 5 → 2 → 4 → 3

    📚 总结

  • 本题考察链表的基础操作:快慢指针、反转链表、链表合并

  • 三步走策略非常经典:

    1. 找中点

    2. 反转后半部分

    3. 交替合并

  • 这道题在面试中很常见,掌握思路后,类似的链表重排问题都能迎刃而解。 🚀

    时间复杂度:O(n)

    空间复杂度:O(1)

相关推荐
阿巴~阿巴~5 分钟前
Linux线程与进程的栈管理、页表机制及线程封装
数据结构·线程·进程·线程封装·页表机制·栈管理
立志成为大牛的小牛22 分钟前
数据结构——三十一、最小生成树(王道408)
数据结构·学习·程序人生·考研·算法
JMzz1 小时前
Rust 中的数据结构选择与性能影响:从算法复杂度到硬件特性 [特殊字符]
开发语言·数据结构·后端·算法·性能优化·rust
星空露珠3 小时前
数独生成题目lua脚本
数据结构·数据库·算法·游戏·lua
给大佬递杯卡布奇诺3 小时前
FFmpeg 基本数据结构 URLContext分析
数据结构·c++·ffmpeg·音视频
极客智造12 小时前
线性数据结构深度解析:数组、链表、栈与队列的实现与应用
数据结构·链表
Zhu_S W13 小时前
Redis跳表:高效有序数据结构的深度剖析
数据结构·数据库·redis
是那盏灯塔14 小时前
【算法】——动态规划之01背包问题
数据结构·c++·算法·动态规划
jinmo_C++14 小时前
数据结构_深入理解堆(大根堆 小根堆)与优先队列:从理论到手撕实现
java·数据结构·算法
Excuse_lighttime15 小时前
排序数组(快速排序算法)
java·数据结构·算法·leetcode·eclipse·排序算法