Question: There is a doubly linked list with next pointer and random pointer (points to an arbitrary node in list). You have to make a copy of the linked list and return. In the end original list shouldn't be modified. Time complexity should be O(n).
Modified structure:
class Node {
int val;
Node next;
Node random;
Node(int x) { val = x; }
}
Example:
In below figure BLUE arrows show next pointer while RED arrows show random pointer.
![](http://2.bp.blogspot.com/-S60dZjrEBow/Taiba5ZEUxI/AAAAAAAAD98/rqD6SVoZex8/s400/Screen%2Bshot%2B2011-04-16%2Bat%2B12.53.14%2BAM.png)
Answer:
1) Create the copy of every node in the list and insert it in original list between current and next node.
- create the copy of A and insert it between A & B..
- create the copy of B and insert it between B & C..
- Continue in this fashion, add the copy of N to Nth node.
![](http://3.bp.blogspot.com/-yQadWpAV7Vg/TaibaoR-2HI/AAAAAAAAD90/6UpGOPmwQFM/s400/Screen%2Bshot%2B2011-04-16%2Bat%2B12.53.27%2BAM.png)
2) Now copy the arbitrary link in this fashion
original->next->random = original->random->next;This works because original->next is nothing but copy of original and Original->random->next is nothing but copy of random.
/*Traverse two nodes in every iteration*/
3) Now restore the original and copy linked lists in this fashion in a single loop.
original->next = original->next->next;
copy->next = copy->next->next;
While doing this, take care of end of list (NULL pointer) and NULL pointer dereference.
So in this manner, we are copying the list in O(n) time and O(1) space complexity.
public class Solution {
public static void main(String[] args) {
Node n1 = new Node(1);
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n4 = new Node(4);
Node n5 = new Node(5);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n1.random = n4;
n2.random = n1;
n3.random = n2;
n4.random = n5;
n5.random = n3;
Node node = copy(n1);
while (node != null) {
System.out.println(node.val);
System.out.println(node.random.val);
node = node.next;
}
}
public static Node copy(Node listHead) {
if (listHead == null) return null;
Node head = listHead;
Node next = null;
//Create the copy of every node in the list and insert
//it in original list between current and next node.
while (head != null) {
Node n = new Node(head.val);
next = head.next;
head.next = n;
n.next = next;
head = next;
}
Node newListHead = listHead.next;
//Copy the arbitrary link for result
head = listHead;
while (head != null) {
head.next.random = head.random.next;
head = head.next.next;
}
head = listHead;
Node temp = head.next;
//restore the original and copy linked lists
while(head != null && temp != null) {
head.next = temp.next;
if (temp.next == null) {
break;
}
temp.next = temp.next.next;
head = head.next;
temp = temp.next;
}
return newListHead;
}
}
From: http://tech-queries.blogspot.com/2011/04/copy-linked-list-with-next-and-random.html