↓Skip to main content
  1. LeetCode/

LeetCode 148: Sort List

·2 mins· ·
LeetCode Medium Linked-List Two-Pointers Divide-and-Conquer Sorting
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-11-17

  • Submissions: Accepted → Time Limit Exceeded ×3 → Accepted ×2

Approach
#

Lists have no random access, so merge sort fits best (Merge Sort Template 3):

  1. Find the middle with fast and slow pointers and cut there (Linked List Template 3). Fast starts at head.next so two nodes split into one and one.
  2. Sort both halves recursively.
  3. Merge the two sorted lists with a dummy.

My Attempts
#

My first accepted version in 2022 was insertion sort (O(n²), which happened to pass); later versions swapping values pairwise were also O(n²) and hit TLE three times. Rewriting it as merge sort in 2026 gave the right complexity.

Solution
#

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

Complexity
#

Time O(n log n), space O(log n) (recursion depth).

Mistakes to Avoid
#

  • Start fast at head.next, or two nodes never split and the recursion never ends.
  • Set slow.next to None when cutting.

Interview Explanation
#

Lists suit merge sort: I cut at the middle found with fast and slow pointers, sort both halves recursively, and merge them with a dummy. Time O(n log n), with only O(log n) recursion space.

Related

LeetCode 324: Wiggle Sort II
·2 mins
LeetCode Medium Array Divide-and-Conquer Greedy Sorting
LeetCode 324 note: sort, split into a small half and a large half, reverse each, and interleave with small values at even indices and large ones at odd indices
LeetCode 143: Reorder List
·2 mins
LeetCode Medium Linked-List Two-Pointers Stack Recursion
LeetCode 143 note: find the middle, reverse the second half, and merge the two alternately, cutting the first half’s tail
LeetCode 215: Kth Largest Element in an Array
·2 mins
LeetCode Medium Array Divide-and-Conquer Sorting Heap-Priority-Queue
LeetCode 215 note: keep a min-heap of size k whose top is the k-th largest, or use quickselect for O(n) on average
LeetCode 347: Top K Frequent Elements
·1 min
LeetCode Medium Array Hash-Table Divide-and-Conquer Sorting
LeetCode 347 note: count first, then take the k most frequent with a size-k heap or a bucket sort indexed by count
LeetCode 75: Sort Colors
·2 mins
LeetCode Medium Array Two-Pointers Sorting Quicksort
LeetCode 75 note: the Dutch flag, with 0s left of low and 2s right of high; after swapping a 2 to high, do not advance, since the swapped-in value is unchecked
LeetCode 82: Remove Duplicates from Sorted List II
·2 mins
LeetCode Medium Linked-List Two-Pointers
LeetCode 82 note: every duplicated value goes, the head included, so use a dummy; on a duplicate skip to the next different value and link prev.next past it