3

I have a singly linked list. Apart from the normal "Next" pointer, there is one more pointer(random ptr) in each node which points to some random node of the list. How to create a clone of such a list? (In less than O(n^2)).

Any suggestion or solution using Java?

Rndm
  • 6,710
  • 7
  • 39
  • 58
  • Hello! Are the random nodes part of the normal list? So all random nodes point somewhere in the list, or they point at some really random stuff? – Balázs Édes Jul 29 '12 at 09:58
  • 2
    @bali182: the question says: there is one more pointer(random ptr) in each node which points **to some random node of the list**. – JB Nizet Jul 29 '12 at 10:12

4 Answers4

1

You could clone all the nodes in order and, during this first pass, build an identity map associating each original node with its clone.

Then do a second pass and, for each original node, get its associated random node, then get the corresponding clone from the map, and associate the clone of the original node to the clone of the random node. The whole process would still be O(n).

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1

There can be two ways :

1) Hash the adresses of all the nodes and store which node the random pointer points to. (Overall complexity would be O(n).)

2) Another O(n) solution would be as shown in the link (does not use any extra space) : http://www.geeksforgeeks.org/archives/1155

Rndm
  • 6,710
  • 7
  • 39
  • 58
1

Here is an answer in O(n) time and O(1) space. (Solutions with a hashtable or association map need O(n) space). shg's link is also a solution in O(n) time and O(1) space.

  • traverse the list to count the number of cells, n.
  • Create an array t of size n, each cell consisting of two pointers a and b. At the end of the algorithm, this will be the copy. But it isn't for now.
  • traverse the original list. For the kth cell c of the original list:
    • let t[k].a be a pointer to c
    • let c.next be a pointer to t[k] (the original list is temporarily destroyed, we will restore it later.). We can now follow pointers back and forth between the original list and t.
  • traverse the original list, and for each cell c, let c.next.b be a pointer to c.random.next. (c.next is a cell in t, so is c.random.next). This way, the b fields of the cells in t are a copy of the structure of the random pointers in the original list.
  • restore the original list: for each k, let t[k].a.next point to t[k+1].a.next
  • make t a linked list: for each k, let t[k].a point to t[k+1].

As opposed to shg's link, this solution has the drawback of requiring a continuous block of size n in memory.

jrouquie
  • 4,315
  • 4
  • 27
  • 43
0

Each node in your list have two references: "Next" and "Random". Assume that "Random" always referenced to the previous. You get double-linked list. Without loss of generality you can apply the procedure of cloning double-linked list to cloning your list. Check this SO answer how they cloned DL list. The complexity should be O(n).

Community
  • 1
  • 1
mishadoff
  • 10,719
  • 2
  • 33
  • 55
  • 2
    Except that if the random pointer doesn't point to the previous node, but to a node that is 175 positions later in the list, the algorithm can't be applied, because you haven't cloned the node yet. – JB Nizet Jul 29 '12 at 10:07