前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【LeetCode热题100】【链表】排序链表

【LeetCode热题100】【链表】排序链表

作者头像
叶茂林
发布2024-04-23 08:32:32
590
发布2024-04-23 08:32:32
举报

题目链接:148. 排序链表 - 力扣(LeetCode)

要排序一个链表,最快的方法是用一个数组将链表节点的值存起来然后排序数组后重新构建链表

但是从面试的角度,我们应该在链表原地排序,这里使用最简单的归并排序

归并排序分三步:拆成两个部分、继续归并排序两个部分、合并两个部分

拆成两个部分,要保持logn的递归树深度,每次拆分需要拆成两半差不多大小的,也就是寻找链表的中间节点,然后以中间节点为界限分成两个链表,即寻找链表的中间节点:使用快慢指针,当快指针到达链表末尾,慢指针即到达链表中间

代码语言:javascript
复制
    ListNode *findMidst(ListNode *head) {
        ListNode *slow = head, *fast = head;
        while (fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        return slow;
    }

然后是考察合并两个有序链表:如果其中一个链表为空,则返回另一个链表,比较两个链表首节点的大小,让小的节点成为新链表的头节点,递归合并后面的

代码语言:javascript
复制
    ListNode *merge(ListNode *l1, ListNode *l2) {
        if (l1 == nullptr)return l2;
        if (l2 == nullptr)return l1;
        if (l1->val < l2->val) {
            l1->next = merge(l1->next, l2);
            return l1;
        }
        l2->next = merge(l1, l2->next);
        return l2;
    }

最后是归并排序链表,先找出链表的中间位置拆分成两个链表,递归归并排序两个链表后合并

代码语言:javascript
复制
    ListNode *sortList(ListNode *left) {
        if (left == nullptr || left->next == nullptr)return left;
        ListNode *midst = findMidst(left);
        ListNode *right = midst->next;
        midst->next = nullptr;
        return merge(sortList(left), sortList(right));
    }

完整代码

代码语言:javascript
复制
class Solution {
public:
    ListNode *merge(ListNode *l1, ListNode *l2) {
        if (l1 == nullptr)return l2;
        if (l2 == nullptr)return l1;
        if (l1->val < l2->val) {
            l1->next = merge(l1->next, l2);
            return l1;
        }
        l2->next = merge(l1, l2->next);
        return l2;
    }

    ListNode *findMidst(ListNode *head) {
        ListNode *slow = head, *fast = head;
        while (fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        return slow;
    }

    ListNode *sortList(ListNode *left) {
        if (left == nullptr || left->next == nullptr)return left;
        ListNode *midst = findMidst(left);
        ListNode *right = midst->next;
        midst->next = nullptr;
        return merge(sortList(left), sortList(right));
    }
};
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com