Problem:
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.
Analyse:
First of all, we should know what is deep copy and shallow copy
Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure or say reference, not the elements. With a shallow copy, two collections now share the individual elements.
Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.
Give an intuitive example:
shallow copy:
ListNode a = new ListNode(1)
ListNode b = a
a —> ListNode(1) <— b
both a and b point to one ListNode(1)
deep copy:
ListNode a = new ListNode(1)
ListNode b = new ListNode(1)
a —>ListNode(1)
b —>ListNode(1)
a and b point to different ListNode(1)
Solution:
Method1: using HashMap
- Check whether this node is in the hashmap. If not, put it into the map;
- Add the copy node into new linklist
- copy the random pointer
- do 1-3 for each node of the original Linklist
time: O(n)
space:O(n)
Method2: Without HashMap
-
1 —> 1’ —> 2 —> 2’ —> 3 —> 3’
-
add random node for each node
-
derive 1’ —> 2’ —> 3’
time O(n)
space O(1)
code(Java)
/*
//Definition for a Node.
class Node {
public int val;
public Node next;
public Node random;
public Node() {}
public Node(int _val,Node _next,Node _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
public class Solution1 {
public Node copyRandomList1(Node head) {
if (head == null) return null;
HashMap<Node, Node> map = new HashMap<>();
Node dummy = new Node();
Node copy = dummy;
Node cur = head;
while (cur != null) {
if (!map.containsKey(cur)) {
map.put(cur, new Node(cur.val, cur.next, cur.random));
}
copy.next = map.get(cur);
if (cur.random != null) {
if (!map.containsKey(cur.random)) {
map.put(cur.random, new Node(cur.random.val, cur.random.next, cur.random.random));
}
copy.next.random = map.get(cur.random);
}
cur = cur.next;
copy = copy.next;
}
return dummy.next;
}
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
Node cur1 = head;
while(cur1 != null) {
Node temp = new Node(cur1.val, cur1.next, cur1.random);
temp.next = cur1.next;
cur1.next = temp;
cur1 = cur1.next.next;
}
Node cur2 = head;
while (cur2 != null) {
if (cur2.random != null) {
cur2.next.random = cur2.random.next;
}
cur2 = cur2.next.next;
}
Node dummy = new Node();
Node cur3 = dummy;
while(head != null) {
cur3.next = head.next;
head.next = cur3.next.next;
cur3 = cur3.next;
head = head.next;
}
return dummy.next;
}
}