↓快轉到主要內容
  1. LeetCode/

LeetCode 148: Sort List

·1 分鐘· ·
LeetCode Medium Linked-List Two-Pointers Divide-and-Conquer Sorting
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2022-11-17

  • 提交紀錄:Accepted → Time Limit Exceeded ×3 → Accepted ×2

解題思路
#

串列不能隨機存取,最適合的是 merge sort(Merge Sort 模板三):

  1. 快慢指針找到中點,從中間切斷(Linked List 模板三)。快指針從 head.next 開始,兩個節點時才會切成一個、一個。
  2. 兩半各自遞迴排好。
  3. 用 dummy 合併兩條已排序的串列。

我的嘗試
#

2022 年第一次 AC 的是插入排序(O(n²),當時剛好沒超時);之後幾版改成兩兩交換值的寫法,也是 O(n²),三次都 TLE。2026 年重寫成 merge sort 才是正確的複雜度。

正確解法
#

class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        slow, fast = head, head.next
        while fast and fast.next:
            slow, fast = slow.next, fast.next.next
        mid, slow.next = slow.next, None
        left, right = self.sortList(head), self.sortList(mid)
        tail = dummy = ListNode()
        while left and right:
            if left.val <= right.val:
                tail.next, left = left, left.next
            else:
                tail.next, right = right, right.next
            tail = tail.next
        tail.next = left or right
        return dummy.next

複雜度
#

時間 O(n log n),空間 O(log n)(遞迴深度)。

要特別避免的錯誤
#

  • 快指針從 head.next 開始,不然兩個節點時切不開,會無限遞迴。
  • 切斷時要把 slow.next 設成 None。

面試口說整理
#

串列適合 merge sort:我用快慢指針找中點切成兩半,遞迴排好兩半再用 dummy 合併。時間 O(n log n),只有遞迴的 O(log n) 空間。

相關文章

LeetCode 324: Wiggle Sort II
·1 分鐘
LeetCode Medium Array Divide-and-Conquer Greedy Sorting
LeetCode 324 解題筆記:排序後分成小的一半和大的一半,各自反轉後交錯放:小的放偶數位置、大的放奇數位置
LeetCode 143: Reorder List
·1 分鐘
LeetCode Medium Linked-List Two-Pointers Stack Recursion
LeetCode 143 解題筆記:找中點、反轉後半段、兩條交錯合併;前半段的尾巴要切斷
LeetCode 215: Kth Largest Element in an Array
·1 分鐘
LeetCode Medium Array Divide-and-Conquer Sorting Heap-Priority-Queue
LeetCode 215 解題筆記:維持大小為 k 的 min-heap,堆頂就是第 k 大;或用 quickselect 平均 O(n)
LeetCode 347: Top K Frequent Elements
·1 分鐘
LeetCode Medium Array Hash-Table Divide-and-Conquer Sorting
LeetCode 347 解題筆記:先計數,再用大小為 k 的 heap 或 bucket sort(次數當 index)取出次數最多的 k 個
LeetCode 75: Sort Colors
·1 分鐘
LeetCode Medium Array Two-Pointers Sorting Quicksort
LeetCode 75 解題筆記:荷蘭國旗:low 左邊都是 0、high 右邊都是 2;遇到 2 換到 high 之後不要前進,換過來的數還沒檢查
LeetCode 82: Remove Duplicates from Sorted List II
·1 分鐘
LeetCode Medium Linked-List Two-Pointers
LeetCode 82 解題筆記:重複的值要全部刪掉,頭也可能被刪,所以用 dummy;發現重複就一路跳到不同的值,再讓 prev.next 接過去