天天看点

[LeetCode 148] Sort List Solution

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

After several months, finally this question is fixed. :) . I am checked my blog, oh, it is two months gone. Keep study every day. Keep focus, keep simple.  

Ideas: this question need O(nlogn), so what we could use is only O(nlogn) sorting algorithms. like merge sort. 

While if we need to use merge sort, we need to split the list into two parts at least. So, we have the divide -conquer-combine.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *sortList(ListNode *head) {
        if(head== nullptr || head->next == nullptr)
        {
            return head;
        }
        
        int total = 0;
        ListNode *p = head;
        ListNode *q = head;
        while(p != nullptr)
        {
            total++;
            p = p -> next;
        }
        
        p = head;
        int count = 0;
        ListNode *last = p;
        while(count < total/2)
        {
            count++;
            last = p;
            p  = p -> next;
        }
        last -> next = NULL;//!important
        ListNode *h1 = sortList(p);//
        ListNode *h2 = sortList(q);//divide
        
        return MergeSorting(h1, h2);//
    }
    
    private:
        ListNode *MergeSorting(ListNode *p, ListNode *q)
        {
            ListNode *TEMP = new ListNode(0);
            ListNode *cur = TEMP;
            
            while(p != nullptr && q != nullptr)
            {
                if(p->val <= q->val)
                {
                    cur->next = p;
                    p = p -> next;
                }
                else
                {
                    cur->next = q;
                    q = q ->next;
                } 
                cur = cur -> next;
            }
            
            if(p == nullptr)
            {
                cur ->next = q;
            }
            
            if(q == nullptr)
            {
                cur -> next = p;
            }
            cur = TEMP -> next;
            
            delete TEMP;//!important, or can not pass OJ
            
            return cur;
        }
};
           

 Note:

  • Divide: Divide the n-element sequence to be sorted into two subsequences of n/2 elements each.
  • Conquer: Sort the two subsequences recursively using Merge Sort.
  • Combine: Merge the two sorted subsequences to produce the sorted answer.