Insertion sort list
Source: https://leetcode.com/problems/insertion-sort-listTags: linked list, recursion, monthly challenge
Problem
Implement insertion sort on a linked list of numbers.
Some questions to ask
- Return a new list? Or perform sorting in-place?
- Are the numbers integers or floats?
- Can the list be empty?
Approach
Let our solution be a function parameterised by the input list (head
)
and an accumulator list (res
).
We process each element of the list in turn and accumulate the
sorted elements in a new list.
At each iteration, we insert head.val
into res
(using the insertion
sort algorithm), and recursively call our solution on the tail of
the input list (head.next
) with the new res
.
The invariant is that res
is always sorted.
The base case is when head is None
, where we return the accumulator.
To insert head.val
into res
, we traverse the res
list with two pointers,
prev
and curr
, and insert head.val
where prev.val <= head.val <= curr.val
,
i.e. create new node and update pointers.
def insertionSortList(head: ListNode, result: ListNode = None) -> ListNode:
"""Sort linked list represented by 'head' using insertion sort,
and return new sorted linked list."""
if head is None:
return result
tail = head.next
node = ListNode(head.val)
prev = None
curr = result
while curr is not None and node.val > curr.val:
prev = curr
curr = curr.next
if prev is None:
node.next = curr
return insertionSortList(tail, node)
else:
prev.next = node
node.next = curr
return insertionSortList(tail, result)
Complexity
Let n be the length of the linked list.
- O(n^2) time, as the worst-case number of comparions is 1 + 2 + … + n-1 = n(n-1)/2
- O(n) space, as you keep track of the input and ouput lists