首页 > 代码库 > LeetCode "Sort List"

LeetCode "Sort List"

First I implemented it by QuickSort, but got a TLE:

class Solution {public:    struct Pair    {        Pair(ListNode *pS, ListNode *pE) : pStart(pS), pEnd(pE)        {}        ListNode *pStart;        ListNode *pEnd;    };    void sort(ListNode *pStart, ListNode *pEnd)    {        if(!pStart) return;        if(pStart == pEnd) return;        queue<Pair> q; q.push(Pair(pStart, pEnd));        while(!q.empty())        {            Pair &in = q.front();            if(in.pStart == in.pEnd)            {                q.pop(); continue;            }            //    Pivot            ListNode *pMid = in.pStart;            int mid = in.pStart->val;            //    Iterate            ListNode *p = in.pStart->next;            while(p != in.pEnd)            {                if(p->val <= mid)                {                    int tmp = pMid -> val;                    pMid -> val = p->val;                    p->val = tmp;                    pMid = pMid->next;                                }                p = p->next;            }            //            q.push(Pair(in.pStart, pMid));            if(in.pStart != pMid) q.push(Pair(pMid, in.pEnd));            else q.push(Pair(pMid->next, in.pEnd));            q.pop();        }    }    ListNode *sortList(ListNode *head) {        if(!head || head->next == NULL) return head;         sort(head, NULL);        return head;    }};
View Code

 And Merge Sort works:

class Solution {public:    struct Pair    {        Pair(ListNode *pS, ListNode *pE) : pStart(pS), pEnd(pE)        {}        ListNode *pStart;        ListNode *pEnd;    };    ListNode *merge(ListNode *p0, int cnt0, ListNode *p1, int cnt1)    {        if(!p0 && !p1) return NULL;        if(p0 && !p1) return p0;        if(!p0 && p1) return p1;        ListNode *pHead = new ListNode(std::numeric_limits<int>::min());        ListNode *pTgt = pHead;        while(cnt0 && cnt1)        {            if(p0->val <= p1->val)            {                ListNode *pNew = new ListNode(p0->val);                pTgt->next = pNew;                pTgt = pTgt->next;                p0 = p0->next;                cnt0--;            }            else            {                ListNode *pNew = new ListNode(p1->val);                pTgt->next = pNew;                pTgt = pTgt->next;                p1 = p1->next;                cnt1--;            }        }        if(cnt0)        {            while(cnt0)            {                ListNode *pNew = new ListNode(p0->val);                pTgt->next = pNew;                pTgt = pTgt->next;                p0 = p0->next;                cnt0--;            }        }        if(cnt1)        {            while(cnt1)            {                ListNode *pNew = new ListNode(p1->val);                pTgt->next = pNew;                pTgt = pTgt->next;                p1 = p1->next;                cnt1--;            }        }                pTgt = pHead->next;        delete pHead;        return pTgt;    }    ListNode *sort(ListNode *pStart, int cnt)    {        if(!pStart || cnt == 1) return pStart;        int cnt0 = cnt / 2;        int cnt1 = cnt - cnt / 2;        //    Find half        ListNode *p = pStart;        int tmp = cnt0;        while(tmp--) p = p->next;        //        ListNode *pl = sort(pStart, cnt0);        ListNode *pr = sort(p, cnt1);        return merge(pl, cnt0, pr, cnt1);    }    ListNode *sortList(ListNode *head) {        if(!head || head->next == NULL) return head;                 //     Get count        int cnt = 0;        ListNode *p = head;        while(cnt++, p) p = p->next;                cnt --;        //    Go        ListNode *pret = sort(head, cnt);        return pret;    }};

In the quicksort implementation, in each iteration, each item will be visited so there are a lot of list node visit. MergeSort is more straightforward and faster.