Sort List – Solution & Complexity

Solution Walkthrough

  1. Step 1: Warm up by collecting values, sorting them, and rebuilding the list

    A straightforward approach is to walk the linked list once, copy every value into an array, sort that array, and then build a new sorted linked list from those values. This is easy to reason about and still runs in O(n log n) time, but it uses O(n) extra space for the copied values and rebuilt nodes.

    def sort_list(head: ListNode) -> ListNode:
        values = []
        current = head
        while current is not None:
            values.append(current.val)
            current = current.next
    
        values.sort()
    
        dummy = ListNode()
        tail = dummy
        for value in values:
            tail.next = ListNode(value)
            tail = tail.next
    
        return dummy.next
  2. Step 2: Use merge sort directly on the linked list for the optimal interview answer

    The optimal linked-list solution uses top-down merge sort. Split the list into two halves with slow and fast pointers, recursively sort each half, then merge the two sorted linked lists. Every level touches each node once, so the time complexity is O(n log n), and the extra space is O(log n) from the recursion stack.

    def sort_list(head: ListNode) -> ListNode:
        if head is None or head.next is None:
            return head
    
        slow = head
        fast = head.next
        while fast is not None and fast.next is not None:
            slow = slow.next
            fast = fast.next.next
    
        right_head = slow.next
        slow.next = None
    
        left_sorted = sort_list(head)
        right_sorted = sort_list(right_head)
    
        dummy = ListNode()
        tail = dummy
    
        while left_sorted is not None and right_sorted is not None:
            if left_sorted.val <= right_sorted.val:
                tail.next = left_sorted
                left_sorted = left_sorted.next
            else:
                tail.next = right_sorted
                right_sorted = right_sorted.next
            tail = tail.next
    
        tail.next = left_sorted if left_sorted is not None else right_sorted
        return dummy.next

FAQ