AfterAcademy Tech
•
12 Sep 2020

Difficulty: Hard
Asked in: Amazon, Google
Problem Description
Sort a linked list using Merge Sort.
Example 1
Input: 44->2->14->37
Output: 2->14->37->44
Explanation: After sorting, 44->2->14->37 becomes 2->14->37->44.
Read about linked list properties from here.
The most preferable sorting technique used for sorting a linked list is Merge Sort. All other sorting algorithms are quadratic algorithms and approaches like Quick Sort and Heap sort perform poorly due to the fact that of slow random access of the linked list.
Let's take 3 -> 2 -> 4 -> 1 -> Null for example
We separate 3 -> 2 -> 4 -> 1 -> Null into 3 -> 2 -> Null and 4 -> 1 -> Null;
We separate 3 -> 2 -> Null into 3 -> Null and 2 -> Null;
Merge them into 2 -> 3 -> Null;
We separate 4 -> 1 -> Null into 4 -> Null and 1 -> Null;
Merge them into 1 -> 4 -> Null;
Merge 2 -> 3 -> Null and 1 -> 4 -> Null into 1 -> 2 -> 3 -> 4 -> Null.
You must have read about Merge sort in an array that uses the divide and conquer approach. We will do the sorting for the linked list in a similar way as we did in sorting the array.
Definition of the singly linked list passed to the function:
class ListNode {
int val;
ListNode *next;
};
So, we will have to understand how subproblems will look like. Imagine a sub-linked list with a head pointer. Here’s how merge sort uses divide-and-conquer:
In conclusion, there will be 3 different functions required.
The solution will be recursive, so we will need a base case for the mergeSort function. The base case will be the case when the linked list has none or only one element, in that way the list with zero or one node is already sorted.
Try solving this problem here.
Pseudo Code
ListNode sortList(ListNode head) {
if(head is NULL or head.next is NULL)
return head
return mergeSort(head)
}
ListNode mergeSort(ListNode head)
{
if(head is NULL or head.next is NULL)
return head
ListNode list1
ListNode list2
// Divide linked list into two halves
// list1 and list2 are passed by reference
findHalves(head, &list1, &list2)
ListNode a = mergeSort(list1)
ListNode b = mergeSort(list2)
// merge the two lists
return merge(a,b)
}
ListNode merge(ListNode List1, ListNode List2)
{
ListNode result = NULL
if(List1 == NULL)
return list2
if(List2 == NULL)
return list1
if(List1.val <= List2.val)
{
result = List1;
result.next = merge(List1.next, List2)
}
else
{
result = List2;
result.next = merge(List1, List2.next)
}
return result
}
void findHalves(ListNode head, ListNode list1, ListNode s2) {
ListNode slow = head
ListNode fast = head
while(fast != NULL)
{
fast = fast.next
if(fast != NULL and fast.next != NULL)
{
slow = slow.next
fast = fast.next
}
}
s1 = head
s2 = slow.next
slow.next = NULL
}
Complexity Analysis
Time Complexity: O(n log n)
Space Complexity: O(n log n)
Critical Ideas To Think
n nodes.findHalves() ?Happy coding! Enjoy Algorithms.
AfterAcademy Tech
Merge k sorted linked lists and return it as one sorted list.

AfterAcademy Tech
Merge two sorted linked lists and return it as a new sorted list. The new list should be made by splicing together the nodes of the first two lists.

AfterAcademy Tech
Merge sort is a divide-and-conquer algorithm based on the idea of breaking down a list into several sub-lists until each sublist consists of a single element and merging those sublists in a manner that results into a sorted list.

AfterAcademy Tech
Sort a linked list using insertion sort and return its head.
