Insertion Sort List — Solution in Python, Java & C++
Insertion Sort List solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem on sorting.
Insertion Sort List is a medium coding problem on sorting, asked in Amazon and Microsoft interviews.
- Difficulty: Medium
- Topics: Sorting
- Asked at: Amazon, Microsoft
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Given the head of a singly linked list, sort it in ascending order using insertion sort, and return the head of the sorted list.
Insertion sort keeps a sorted part that starts empty; at each step it takes the next node of the unsorted input and inserts it at its correct place in the sorted part, until no input remains.
Example 1
Input: head = [4,2,1,3]
Output: [1,2,3,4]
Example 2
Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]
Example 3
Input: head = [2,2,1]
Output: [1,2,2]
Explanation: Equal values simply sit next to each other.
Constraints
The number of nodes in the list is in the range [1, 5000]-5000 <= Node.val <= 5000
Hints for Insertion Sort List
Hint 1
Build the sorted list separately, starting from a dummy node, and move input nodes into it one at a time.
Hint 2
To insert a node, walk the sorted list from the dummy until the next node is larger than the one being inserted.
Hint 3
Remember the input node's
nextbefore relinking it — that is where the input continues.
How to solve Insertion Sort List
Keep a sorted list behind a dummy node. Detach each node of the input in turn and splice it in after the last sorted node whose value does not exceed it.
Approach
- Create
dummy(the sorted list starts empty) and setcur = head. - While
curis not null: savenext = cur.next. - Walk
prevfromdummywhileprev.nextexists andprev.next.val <= cur.val. - Splice:
cur.next = prev.next,prev.next = cur; thencur = next. - Return
dummy.next.
Why it works
The list behind dummy is sorted before each step, and inserting cur after the last node not greater than it keeps it sorted. Every input node is moved exactly once, so at the end the sorted list holds all of them.
Complexity
- Time —
O(n²) in the worst case (O(n) for an already sorted list if you first check the last sorted node) - Space —
O(1)
Pitfalls
- Losing the rest of the input by relinking
curbefore savingcur.next. - Starting the search from the head of the input rather than the sorted list.
- Using
<instead of<=also sorts correctly, but<=keeps equal values in their original order (a stable sort).
Reference solution
Python
from typing import Optional
def insertionSortList(head: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(0)
cur = head
while cur:
nxt = cur.next
prev = dummy
while prev.next and prev.next.val <= cur.val:
prev = prev.next
cur.next = prev.next
prev.next = cur
cur = nxt
return dummy.nextJava
public static ListNode insertionSortList(ListNode head) {
ListNode dummy = new ListNode(0), cur = head;
while (cur != null) {
ListNode nxt = cur.next, prev = dummy;
while (prev.next != null && prev.next.val <= cur.val) prev = prev.next;
cur.next = prev.next;
prev.next = cur;
cur = nxt;
}
return dummy.next;
}C++
ListNode* insertionSortList(ListNode* head) {
ListNode dummy(0);
ListNode* cur = head;
while (cur) {
ListNode* nxt = cur->next;
ListNode* prev = &dummy;
while (prev->next && prev->next->val <= cur->val) prev = prev->next;
cur->next = prev->next;
prev->next = cur;
cur = nxt;
}
return dummy.next;
}JavaScript
var insertionSortList = function(head) {
var dummy = new ListNode(0), cur = head;
while (cur !== null) {
var nxt = cur.next, prev = dummy;
while (prev.next !== null && prev.next.val <= cur.val) prev = prev.next;
cur.next = prev.next;
prev.next = cur;
cur = nxt;
}
return dummy.next;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 274 sorting problems · the whole catalogue
Learn the technique: Sorting Algorithms