Skip to content

Commit 4f5d514

Browse files
committed
Create CopyLLWithRandomPointer
1 parent 309b7d0 commit 4f5d514

File tree

1 file changed

+356
-0
lines changed

1 file changed

+356
-0
lines changed

CopyLLWithRandomPointer

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
2+
************************************ I. Using Intelligent Algorithm *****************************************
3+
/*
4+
* Question: Given a LL with next and random pointers which point to any other node in LL
5+
* Devise a algorithm to copy this LL
6+
*
7+
* Source: http://www.careercup.com/question?id=5412018236424192
8+
*
9+
* Algorithm:
10+
*
11+
*
12+
I. Using Intelligent Algorithm:
13+
14+
Node* CopyLinkedList(Node* head) {
15+
16+
Node* n = head;
17+
18+
// First pass, insert a copy next to the code.
19+
while (n) {
20+
Node* n1 = new Node();
21+
n1->data = n->data;
22+
n1->next = n->next;
23+
n->next = n1;
24+
n = n->next->next;
25+
}
26+
27+
// Second pass, set random pointer.
28+
n = head;
29+
while (n) {
30+
n->next->random = n->random->next;
31+
n = n->next->next;
32+
}
33+
34+
// Third pass, detach two lists.
35+
n = head;
36+
Node* head1 = n->next;
37+
while (n) {
38+
Node* temp = n->next->next;
39+
n->next->next = temp ? temp->next : nullptr;
40+
n->next = temp;
41+
n = temp;
42+
}
43+
return head1;
44+
}
45+
46+
47+
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+
58+
II. Using HashMap
59+
60+
A good linear way is to use a map.
61+
62+
1) Go through your linked list, and for each node v, create a new node u, such that u->data = v->data.
63+
Now store (v,u) in your map.
64+
{Note, doesn't matter where you set the u->next, just leave the new nodes dangling in the air}
65+
66+
2) Now go through your original linked list again, and visit every v.
67+
Now do lookups in the map for every v in your original linked list....
68+
Look up v to get u.
69+
Call v->next as x
70+
Call v->random as y
71+
Now set u->next->map[x], u->random=map[y] .
72+
73+
CONS OF USING HASHMAP:
74+
hash maps need something to hash on.. what are you assuming that is?
75+
The value of the node? What if several nodes have the same value?
76+
Your map is going to get messed up pretty quick
77+
78+
79+
80+
VERY IMP NOTE:
81+
HENCE, HASHMAP CAN ONLY BE USED IF EVERY NODE.DATA IS UNIQUE WHEREAS THE FIRST APPROACH
82+
OF USING INTELLIGENT ALGORITHM CAN BE USED FOR ANY CASE (EVEN IF NODE.DATA IS NOT UNIQUE)
83+
84+
*/
85+
86+
87+
package LLCopyWithRandomPointer;
88+
89+
public class UsingInteligentAlgorithms {
90+
public static void main(String[] args) {
91+
// create the head node
92+
Node head=new Node(10);
93+
// create the LL
94+
head.appendToTail(20).appendToTail(30).appendToTail(40).appendToTail(50);
95+
96+
// set the random pointers
97+
head.random=head.next.next.next; //10.random = 40
98+
head.next.random = head; // 20.random=10
99+
head.next.next.random = head.next.next.next.next; //30.random=50
100+
head.next.next.next.random = head.next; // 40.random=20
101+
head.next.next.next.next.random = head.next.next; //50.random = 30
102+
103+
// print original LL
104+
System.out.println("Original LL: ");
105+
printLL(head);
106+
107+
// copy the linkedlist
108+
Node head1 = copyLLWithRandomPointer(head);
109+
110+
// print the copied linked list
111+
System.out.println("Copied LL: ");
112+
printLL(head1);
113+
114+
115+
}
116+
117+
private static Node copyLLWithRandomPointer(Node head) {
118+
119+
// First pass, insert a copy next to the code. Example: a a' b b' c c' NULL
120+
Node n = head;
121+
while(n!=null){
122+
Node copy = new Node(n.data);
123+
copy.next = n.next;
124+
n.next = copy;
125+
// traverse through the LL
126+
n=n.next.next;
127+
}
128+
129+
// Second pass, set random pointer.
130+
n=head;
131+
while(n!=null){
132+
n.next.random = n.random.next;
133+
// traverse through the LL
134+
n=n.next.next;
135+
}
136+
137+
// Third pass, detach two lists.
138+
n = head;
139+
Node head1 = n.next;
140+
while(n!=null){
141+
Node temp = n.next.next;
142+
if(temp!=null)
143+
n.next.next = temp.next;
144+
else
145+
n.next.next = null;
146+
n.next = temp;
147+
// traverse through the LL
148+
n=temp;
149+
}
150+
151+
return head1;
152+
}
153+
154+
private static void printLL(Node head) {
155+
Node n = head;
156+
while(n!=null){
157+
System.out.println("Data:"+n.data+" Random:"+n.random.data);
158+
n=n.next;
159+
}
160+
System.out.println();
161+
}
162+
}
163+
164+
class Node{
165+
public int data;
166+
public Node next;
167+
public Node random;
168+
169+
public Node(int data){
170+
this.data=data;
171+
this.next=null;
172+
this.random=null;
173+
}
174+
public Node appendToTail(int data){
175+
Node n = this;
176+
Node prev = null;
177+
while(n!=null){
178+
prev=n;
179+
n=n.next;
180+
}
181+
prev.next=new Node(data);
182+
return prev.next;
183+
}
184+
}
185+
/*
186+
* Analysis:
187+
* Time Complexity: we run 3 passes hence 3n, asymptotically it is O(n)
188+
* Space Complexity: O(1)
189+
*/
190+
191+
************************************ II. Using HashMap *****************************************
192+
193+
/*
194+
* Question: Given a LL with next and random pointers which point to any other node in LL
195+
* Devise a algorithm to copy this LL
196+
*
197+
* Source: http://www.careercup.com/question?id=5412018236424192
198+
*
199+
* Algorithm:
200+
*
201+
*
202+
I. Using Intelligent Algorithm:
203+
204+
Node* CopyLinkedList(Node* head) {
205+
206+
Node* n = head;
207+
208+
// First pass, insert a copy next to the code.
209+
while (n) {
210+
Node* n1 = new Node();
211+
n1->data = n->data;
212+
n1->next = n->next;
213+
n->next = n1;
214+
n = n->next->next;
215+
}
216+
217+
// Second pass, set random pointer.
218+
n = head;
219+
while (n) {
220+
n->next->random = n->random->next;
221+
n = n->next->next;
222+
}
223+
224+
// Third pass, detach two lists.
225+
n = head;
226+
Node* head1 = n->next;
227+
while (n) {
228+
Node* temp = n->next->next;
229+
n->next->next = temp ? temp->next : nullptr;
230+
n->next = temp;
231+
n = temp;
232+
}
233+
return head1;
234+
}
235+
236+
237+
238+
239+
240+
241+
242+
243+
244+
245+
246+
247+
248+
II. Using HashMap
249+
250+
A good linear way is to use a map.
251+
252+
1) Go through your linked list, and for each node v, create a new node u, such that u->data = v->data.
253+
Now store (v,u) in your map.
254+
{Note, doesn't matter where you set the u->next, just leave the new nodes dangling in the air}
255+
256+
2) Now go through your original linked list again, and visit every v.
257+
Now do lookups in the map for every v in your original linked list....
258+
Look up v to get u.
259+
Call v->next as x
260+
Call v->random as y
261+
Now set u->next->map[x], u->random=map[y] .
262+
263+
CONS OF USING HASHMAP:
264+
hash maps need something to hash on.. what are you assuming that is?
265+
The value of the node? What if several nodes have the same value?
266+
Your map is going to get messed up pretty quick
267+
268+
269+
270+
VERY IMP NOTE:
271+
HENCE, HASHMAP CAN ONLY BE USED IF EVERY NODE.DATA IS UNIQUE WHEREAS THE FIRST APPROACH
272+
OF USING INTELLIGENT ALGORITHM CAN BE USED FOR ANY CASE (EVEN IF NODE.DATA IS NOT UNIQUE)
273+
274+
*/
275+
276+
package LLCopyWithRandomPointer;
277+
278+
import java.util.HashMap;
279+
280+
public class UsingHashMap {
281+
public static void main(String[] args) {
282+
// create the head node
283+
Node head=new Node(10);
284+
// create the LL
285+
head.appendToTail(20).appendToTail(30).appendToTail(40).appendToTail(50);
286+
287+
// set the random pointers
288+
head.random=head.next.next.next; //10.random = 40
289+
head.next.random = head; // 20.random=10
290+
head.next.next.random = head.next.next.next.next; //30.random=50
291+
head.next.next.next.random = head.next; // 40.random=20
292+
head.next.next.next.next.random = head.next.next; //50.random = 30
293+
294+
// print original LL
295+
System.out.println("Original LL: ");
296+
printLL(head);
297+
298+
// copy the linkedlist
299+
Node head1 = usingHashMap(head);
300+
301+
// print the copied linked list
302+
System.out.println("Copied LL: ");
303+
printLL(head1);
304+
305+
306+
}
307+
308+
private static Node usingHashMap(Node head) {
309+
310+
/* VERY IMP NOTE:
311+
HENCE, HASHMAP CAN ONLY BE USED IF EVERY NODE.DATA IS UNIQUE WHEREAS THE FIRST APPROACH
312+
OF USING INTELLIGENT ALGORITHM CAN BE USED FOR ANY CASE (EVEN IF NODE.DATA IS NOT UNIQUE)
313+
*/
314+
315+
HashMap<Node,Node> map = new HashMap<Node,Node>();
316+
317+
// First Pass: Put all the nodes in the HashMap
318+
Node n = head;
319+
while(n!=null){
320+
map.put(n,new Node(n.data));
321+
// iterate through the LL
322+
n=n.next;
323+
}
324+
325+
// Second Pass: Copy the next and random pointers
326+
n = head;
327+
Node head1 = map.get(n);
328+
while(n!=null){
329+
Node copy = map.get(n);
330+
Node next = n.next;
331+
Node random = n.random;
332+
333+
copy.next = map.get(next);
334+
copy.random = map.get(random);
335+
336+
// iterate through the LL
337+
n=n.next;
338+
}
339+
340+
return head1;
341+
}
342+
343+
private static void printLL(Node head) {
344+
Node n = head;
345+
while(n!=null){
346+
System.out.println("Data:"+n.data+" Random:"+n.random.data);
347+
n=n.next;
348+
}
349+
System.out.println();
350+
}
351+
}
352+
/*
353+
* Analysis:
354+
* Time Complexity: we run 2 passes hence 2n, asymptotically it is O(n)
355+
* Space Complexity: O(n), used by HashMap
356+
*/

0 commit comments

Comments
 (0)