Given a linked list with each node having an additional random pointer that points to any random node of the linked list or null, update the random pointer in each linked list node to point to a node with maximum value to its right.

Practice this problem

A naive solution would be to traverse the list, and for each encountered node, find the node with maximum value by traversing the remaining list again. The time complexity of this approach is O(n2), where n is the total number of nodes in the linked list.

 
If the given list was doubly linked, we could have easily updated the random pointers with maximum value node by traversing the list from the end. This would require only a single traversal of the linked list.

 
We can still solve this problem in linear time for a singly linked list. The idea is to reverse the list first, traverse the reversed list, and maintain a pointer that points to the node with the maximum value found so far. Then for each encountered node, update its random pointer to point to the maximum value node so far. Finally, restore the list’s original order (i.e., reverse it again).

The algorithm can be implemented as follows in C++, Java, and Python:

C++


Download  Run Code

Output:

Original linked list: 5(X) —> 10(X) —> 7(X) —> 9(X) —> 4(X) —> 3(X) —> X
Final Linked List: 5(10) —> 10(9) —> 7(9) —> 9(4) —> 4(3) —> 3(X) —> X

Java


Download  Run Code

Output:

Original linked list: 5(X) —> 10(X) —> 7(X) —> 9(X) —> 4(X) —> 3(X) —> X
Final Linked List: 5(10) —> 10(9) —> 7(9) —> 9(4) —> 4(3) —> 3(X) —> X

Python


Download  Run Code

Output:

Original linked list: 5(X) —> 10(X) —> 7(X) —> 9(X) —> 4(X) —> 3(X) —> X
Final Linked List: 5(10) —> 10(9) —> 7(9) —> 9(4) —> 4(3) —> 3(X) —> X

The time complexity of the above solution O(n2), and doesn’t require any extra space. But it requires three traversals of the linked list.

 
We can simplify the above code using recursion. The idea is to recursively call the next node of the linked list and update each node’s random pointer with the maximum value node found so far as the recursion unfolds. This is demonstrated below in C++, Java, and Python:

C++


Download  Run Code

Output:

Original linked list: 5(X) —> 10(X) —> 7(X) —> 9(X) —> 4(X) —> 3(X) —> X
Final Linked List: 5(10) —> 10(9) —> 7(9) —> 9(4) —> 4(3) —> 3(X) —> X

Java


Download  Run Code

Output:

Original linked list: 5(X) —> 10(X) —> 7(X) —> 9(X) —> 4(X) —> 3(X) —> X
Final Linked List: 5(10) —> 10(9) —> 7(9) —> 9(4) —> 4(3) —> 3(X) —> X

Python


Download  Run Code

Output:

Original List: (5, ‘X’) —> (10, ‘X’) —> (7, ‘X’) —> (9, ‘X’) —> (4, ‘X’) —> (3, ‘X’) —> X
Final List: (5, 10) —> (10, 9) —> (7, 9) —> (9, 4) —> (4, 3) —> (3, ‘X’) —> X