Copying a regular linked list in linear time is obviously trivial. The only part that makes this interesting is the "random" pointer. Presumably, by "random" you really mean that it points to another randomly selected node in the same linked list. Presumably, it is assumed that a copy of the linked list recreates exactly the same structure, i.e. The βnextβ pointers create a linear list, and the other pointers refer to the same relative nodes (for example, if a random pointer in the first node of the source list points to the fifth node in the source list, then a random pointer in the duplicate list also points to the fifth node of the duplicate list .
Doing this in N 2 time is pretty simple. Duplicate the list first, usually ignoring the random pointer. Then go through the source list one node at a time, and for each node again scroll through the list to find which node of the list the random pointer refers to (i.e. how many nodes you go through next
to find the next
pointer containing that same address as the random
pointer of the current node.Then go through the duplicate list and cancel it: find N th node, and put this random pointer in the current node.
The reason for this is O (N 2 ), first of all, it is a linear search for the right nodes. To obtain O (N), these searches must be performed with constant complexity instead of linear complexity.
The obvious way to do this is to build a hash table that maps the address of each node in the source list to the position of that node in the list. Then we can build an array containing the addresses of the nodes in the new list.
With this, fixing random pointers is pretty simple. First, we look at the source list using next
pointers, duplicate nodes and create our new list, linked using next
pointers, but leaving only random pointers. As we do this, we insert the address and position of each node in the hash table and the address of each node in a new list in our array.
When we are done with this, we will go through the old list and the new list in lock mode. For each node in the old list, we look at the address in this node with a random pointer. We look at the position associated with this address in our hash table, then we get the node address in the new list at this position and put it in the random pointer of the current node in the new list. Then we move on to the next node in both the old and the new list.
When we are done, we discard / destroy both the hash table and the array, since our new list now duplicates the structure of the old one and we no longer need additional data.