Given two sorted linked lists, merge them without using extra space without modifying the links of the first list. The solution should preserve the sorted order of elements in both lists.

If m and n are the total number of nodes in the first and second list, then the first m smallest nodes in both lists combined should become part of the first list, and the remaining nodes should become part of the second list.

 
For example,

Input:
 
First List: 2 —> 6 —> 9 —> 10 —> 15 —> NULL
Second List: 1 —> 4 —> 5 —> 20 —> NULL
 
Output:
 
First List: 1 —> 2 —> 4 —> 5 —> 6 —> NULL
Second List: 9 —> 10 —> 15 —> 20 —> NULL

Practice this problem

A simple solution would be to use the merge procedure of the merge sort algorithm to merge both lists. After merging both lists, assign the first m smallest nodes to the first linked list and the remaining n nodes to the second linked list where m and n are the total number of elements in the first and second linked list, respectively. We can do this in O(m + n) time and constant space.

 
The above solution violates the problem constraints by modifying links of the first list. However, there is no restriction on swapping data between the linked list nodes. The idea is to compare each node of the first list with the head node of the second list and swap their data if the first list’s current node is greater than the head node of the second list. The first list remains sorted with this data exchange, but the second list’s sorted order might be disturbed. To fix it, pop the front node from the second list and insert it at its correct place into the sorted second list using the sortedInsert() function.

Following is the C, Java, and Python implementation of the idea:

C


Download  Run Code

Output:

Before Merging:
 
First List: 2 —> 6 —> 9 —> 10 —> 15 —> NULL
Second List: 1 —> 4 —> 5 —> 20 —> NULL
 
 
After Merging:
 
First List: 1 —> 2 —> 4 —> 5 —> 6 —> NULL
Second List: 9 —> 10 —> 15 —> 20 —> NULL

Java


Download  Run Code

Output:

Before Merging:
 
First List: 2 —> 6 —> 9 —> 10 —> 15 —> null
Second List: 1 —> 4 —> 5 —> 20 —> null
 
 
After Merging:
 
First List: 1 —> 2 —> 4 —> 5 —> 6 —> null
Second List: 9 —> 10 —> 15 —> 20 —> null

Python


Download  Run Code

Output:

Before Merging:
 
First List: 2 —> 6 —> 9 —> 10 —> 15 —> None
Second List: 1 —> 4 —> 5 —> 20 —> None
 
 
After Merging:
 
First List: 1 —> 2 —> 4 —> 5 —> 6 —> None
Second List: 9 —> 10 —> 15 —> 20 —> None

The worst-case time complexity of the above solution is O(m.n), where m and n are the total number of nodes in the first and second list, respectively. The merging is done in-place, but we might end up traversing the complete second list for each node in the first list. This accounts for O(m.n) time complexity.

The best-case time complexity of the above solution is O(m). The best case happens when both lists are already merged in sorted order, and the sortedInsert() method is never called, which runs in O(n) time.

 
Author: Aditya Goel