algoadvance

The problem is to sort a linked list in O(n log n) time using constant space complexity. You are given the head of the linked list, and you need to return the head of the sorted linked list.

Clarifying Questions

  1. What type of data does each node contain? Each node contains an integer value.

  2. Are there any constraints on the values of the nodes (positive, negative, large numbers)? No, the nodes can contain any integer value.

  3. Is the input list always valid (i.e., no cycles)? Yes, the problem statement assumes a well-formed linked list with no cycles.

  4. What should be returned if the list is empty? If the list is empty (head is None), return None.

Strategy

Code

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def sortList(head: ListNode) -> ListNode:
    if not head or not head.next:
        return head
    
    # Split the list into two halves
    slow, fast = head, head.next
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
    
    mid = slow.next
    slow.next = None
    
    # Recursively split & sort
    left = sortList(head)
    right = sortList(mid)
    
    # Merge sorted halves
    return merge(left, right)

def merge(left: ListNode, right: ListNode) -> ListNode:
    dummy = ListNode()
    tail = dummy
    
    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
    
    if left:
        tail.next = left
    if right:
        tail.next = right
    
    return dummy.next

Time Complexity

Combining these, the overall time complexity is O(n log n). The space complexity is O(1), assuming that the recursion stack space does not count as extra space, which aligns with the problem’s constraints.

Try our interview co-pilot at AlgoAdvance.com