-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCopyListWithRandomPointer_138.java
More file actions
112 lines (94 loc) · 3.46 KB
/
CopyListWithRandomPointer_138.java
File metadata and controls
112 lines (94 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
* ----------------------------------------------------------------------------
Copy List with Random Pointer
- A linked list is given such that each node contains an additional
random pointer which could point to any node in the list or null.
- Return a deep copy of the list.
* ----------------------------------------------------------------------------
*
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
/**
* There are three ways:
* 1. Two Passes
* - First pass: deep copy the next pointer
* - Second pass: link the random pointer
* - When linking the random pointer, we need to search for the copied node
* for each random pointer, which O(n)
* - Time Complexity: O(n^2) in total, and no extra space
*
* 2. HashMap
* - Instead of search for copied node for each random pointer,
* we hash the copied one for the original one:
* HashMap<Original, Copied>
* - Time Complexity: O(n), and space O(n).
* - We can further improve this to single pass:
* treating next and random pointer the same way
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) return null;
// ori -> copied
HashMap<RandomListNode, RandomListNode> map = new HashMap<>();
RandomListNode chead = new RandomListNode(head.label);
map.put(head, chead);
RandomListNode cor = head, cur = chead;
while(cor != null) {
// next pointer
if (cor.next == null) cur.next = null;
else if (map.containsKey(cor.next))
cur.next = map.get(cor.next);
else { cur.next = new RandomListNode(cor.next.label);
map.put(cor.next, cur.next);
}
// random pointer
if (cor.random == null) cur.random = null;
else if (map.containsKey(cor.random))
cur.random = map.get(cor.random);
else { cur.random = new RandomListNode(cor.random.label);
map.put(cor.random, cur.random);
}
cor = cor.next;
cur = cur.next;
}
return chead;
}
}
//------------------------------------------------------------------------------
/**
* 3. O(n) time O(1) space
* - Space or time is wasted for search for the copied node
* - Avoid this by connecting the original node to the copied node
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
RandomListNode dhead = new RandomListNode(0),
cur = dhead, cor = head, cornext = null;
// construct the copied list
while(cor != null) {
cur.next = cor; cornext = cor.next;
cur = new RandomListNode(cor.label);
cor.next = cur; cor = cornext;
}
// construct the random pointer
cor = head;
while(cor != null) {
cor.next.random = (cor.random == null) ? null : cor.random.next;
cor = cor.next.next;
}
// restore to the original state
cor = head; cur = dhead;
while(cor != null) {
cur.next = cor.next;
cor.next = cor.next.next;
cor = cor.next; cur = cur.next;
}
return dhead.next;
}
}