148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

二分归并法对链表进行排序

1. 首先通过快慢指针把链表拆成前后两半部分。  2. 对前后两半部分分别进行排序。 3.合并两个有序链表。

时间复杂度分析:拆分时间O(n),两部分运算时间2T(n/2),合并时间O(n)

T(n)=2T(n/2)+2O(n),根据主定理,T(n)=nlogn

空间复杂度分析:空间复杂度一般是指除了输入输出之外额外的部分:这个题没有new一个新的指针,所以空间复杂度O(1)。但是如果要是数组的话,二分归并空间复杂度O(n),因为合并数组的时候,如果还是占用原来的空间的话,原来的数就不知道放哪儿了。链表的话,我们只需要更改指针的指向就行了。

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *dummy=new ListNode (0), *p=dummy;
        while(l1 && l2){
            if(l1->val >= l2->val){
                p->next=l2;
                l2=l2->next;
            }
            else{
                p->next=l1;              
                l1=l1->next;
            }
            p=p->next;
        }
        if(l1) p->next=l1;
        if(l2) p->next=l2;
        return dummy->next;
    }

    ListNode* sortList(ListNode* head) {
        if(!head || !head->next) return head;
        ListNode *fast=head, *slow=head, *pre=head;
        while(fast && fast->next){
            pre=slow;
            slow=slow->next;
            fast=fast->next->next;
        }
        pre->next=nullptr;
        head=sortList(head);
        slow=sortList(slow);
        return mergeTwoLists(head,slow);
    }
};

 

你可能感兴趣的:(leetcode)