LeetCode 148. Sort List(C++)

Sort a linked list in O(n log n) time using constant space complexity.

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4

Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

解题思路:

本题还是有点意思的,虽然只是看上去只是链表排序,但是要求时间复杂度O(n log n),空间复杂度O(1)。需要用到归并排序。一般而言,归并排序的空间复杂度为n,但是本题为链表,可以控制在常数级别。

在做本题之前,建议先看看这篇https://blog.csdn.net/qq_41562704/article/details/89429773如何合并两个有序的链表。

归并排序先将节点每两个一组排序,再将每两个小组(即4个节点)排序;但是本题并非数组存储,无法直接到达下一组的起点,所以本题需要用递归,将链表平均分为两半,直到只有单个节点,将两半链表合并(用链接中的方法),根据递归性质,合并的时候,两半的链表都各自排序好的。另外还有一个问题,如何找到链表的中点,这里用到快慢指针法,在判断链表中是否有环的时候常用到。

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        return head == nullptr ? head : mergeSort(head);
    }
private:
    ListNode* mergeSort(ListNode* node){
        if(node->next == nullptr)
            return node;
        ListNode *fast = node, *slow = node, *mid;
        while(fast != nullptr && fast->next != nullptr){
            mid = slow;
            slow = slow->next;
            fast = fast->next->next;
        }
        mid->next = nullptr;
        ListNode* L = mergeSort(node);
        ListNode* R = mergeSort(slow);
        return merge(L, R);
    }
    ListNode* merge(ListNode* L, ListNode* R){
        if(L == nullptr)
            return R;
        if(R == nullptr)
            return L;
        if(L->val <= R->val){
            L->next = merge(L->next, R);
            return L;
        }
        else{
            R->next = merge(L, R->next);
            return R;
        }
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值