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;
        }
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章