[Leetcode] Sort List

题目:

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


思路:O(nlogn)的sort有quick sort, merge sort, heap sort. 首先排除heap sort, heap需要用到O(n)的空间。其次排除quick sort, quick sort需要大量的swap,同时还需要一个指针从后向前移动,单链表不支持这些。事实上,链表排序最好的方法就是merge sort,因为链表很好的克服了merge sort需要额外空间这一缺点。具体做法是递归分解链表,在返回的时候对两个子链表进行合并。


class Solution {
public:
    ListNode *sortList(ListNode *head) {
        if (head == nullptr || head->next == nullptr) return head;   //reach the end
        ListNode* fast = head;
        ListNode* slow = head;
        while (fast->next != nullptr && fast->next->next != nullptr) {
            fast = fast->next->next;
            slow = slow->next;
        }
        ListNode* mid = slow->next;
        slow->next = nullptr;   //break the list
        ListNode* l1 = sortList(head);
        ListNode* l2 = sortList(mid);
        // merge the two sorted sublist
        ListNode dummy(0);
        ListNode* runner = &dummy;
        while (l1 != nullptr || l2 != nullptr) {
            if (l1 == nullptr) {   //l1 is empty
                runner->next = l2;
                l2 = l2->next;
            } else if (l2 == nullptr) {   //l2 is empty
                runner->next = l1;
                l1 = l1->next;
            } else {
                if (l1->val < l2->val) {   //choose l1
                    runner->next = l1;
                    l1 = l1->next;
                } else {   //choose l2
                    runner->next = l2;
                    l2 = l2->next;
                }
            }
            runner = runner->next;
        }
        return dummy.next;
    }
};


总结:递归实际上是生成了一个二叉树,树的根为长度n的链表,第二层为两个n/2的链表,第三层为4个n/4的链表 ... 在merge的时候,每一层都要touch n个节点,因此每一层的复杂度为O(n). 一共有logn层,所以复杂度为O(nlogn).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值