1. 程式人生 > 實用技巧 >python 列舉enum

python 列舉enum

題目描述

給你連結串列的頭結點 head ,請將其按 升序 排列並返回 排序後的連結串列 。

進階:
你可以在 \(O(n \log n)\) 時間複雜度和常數級空間複雜度下,對連結串列進行排序嗎?

示例1:

輸入:head = [4,2,1,3]
輸出:[1,2,3,4]

示例2:

輸入:head = [-1,5,3,4,0]
輸出:[-1,0,3,4,5]

示例3:

輸入:head = []
輸出:[]

提示:

  • 連結串列中節點的數目在範圍 [0, 5 * 104]
  • -105 <= Node.val <= 105

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/sort-list

思路解析

排序的演算法有很多,簡單的排序演算法有類似LeetCode 147 對連結串列進行插入排序。這裡要求時間複雜度為 \(O(n\log n)\),需要考慮稍微快一些的排序演算法,這裡採用歸併排序。
歸併排序並不複雜,但是與常見的陣列排序不同,陣列排序可以在 \(O(1)\) 的時間內找到陣列的中點,並進行遞迴。但是在連結串列中需要找到中點,無法通過 \(O(1)\) 的複雜度直接查詢得到。

這裡採用 快慢指標 的方法來查詢連結串列中點,定義 快指標 和 慢指標,快指標每次移動兩格,慢指標每次移動一格,快指標移動至末尾時,慢指標移動至中點。這裡可能需要細心一些來保證快慢指標不出錯。

程式碼實現

class Solution {
private:
    ListNode* mergeList(ListNode* h1, ListNode* h2) {
        ListNode* dhead = new ListNode();
        ListNode* p1 = h1;
        ListNode* p2 = h2;
        ListNode* p = dhead;
        while(p1 && p2) {
            if(p1->val < p2->val) {
                p->next = p1;
                p = p1;
                p1 = p1->next;
            }
            else {
                p->next = p2;
                p = p2;
                p2 = p2->next;
            }
        }
        if(p1) p->next = p1;
        else if(p2) p->next = p2;
        return dhead->next;
    }
    ListNode* mergeSort(ListNode* head) {
        if((!head) || (!head->next)) return head;
        ListNode* mid = head;
        ListNode* fast = head;
        while(fast && fast->next) {
            fast = fast->next;
            if(!fast->next) break;
            fast = fast->next;
            mid = mid->next;
        }
        ListNode* h1 = head;
        ListNode* h2 = mid->next;
        mid->next = nullptr;
        return mergeList(mergeSort(h1), mergeSort(h2));
    }
public:
    ListNode* sortList(ListNode* head) {
        return mergeSort(head);
    }
};
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */