O(n) time and O(1) space.
Three steps.
Copy all new nodes and link them next to the old one;
Copy all random links for new nodes;
Restore both old list and new list.
Example.
1->2->3->null
1->1`->2->2`->3->3`->null
Restore to,
1->2->3->null
1`->2`->3`->null
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null)
return null;
// Link all new nodes next to the old nodes
RandomListNode temp = head;
while (temp != null) {
RandomListNode newNode = new RandomListNode(temp.label);
RandomListNode next = temp.next;
temp.next = newNode;
newNode.next = next;
temp = temp.next.next;
}
// Copy random links for new nodes
temp = head;
while (temp != null) {
RandomListNode newNode = temp.next;
if (temp.random != null) // if random link in the origin list is null, iterate to the next
newNode.random = temp.random.next;
temp = temp.next.next;
}
// Set all next links in new nodes to new nodes
RandomListNode newHead = head.next; // save the head of new list, we will modify the next link of head (origin list)
temp = head;
while (temp != null) {
RandomListNode next = temp.next.next;
RandomListNode newNode = temp.next;
if (next != null) // take care of the end of the list
newNode.next = next.next;
temp.next = next; // need to restore the origin list
temp = next;
}
return newHead;
}
}
Using a hashmap to save the <old, new> pairs,
then set next and random link for new created nodes.
O(n) time and space complexity.
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
// a hashmap to save <oldNode, newNode> pairs
HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
// create mapping between new nodes and old nodes
RandomListNode temp = head;
while (temp != null) {
map.put(temp, new RandomListNode(temp.label));
temp = temp.next;
}
// link next and random links for new nodes
// iterate the hashmap
for (Map.Entry<RandomListNode, RandomListNode> entry : map.entrySet()) {
// link next
entry.getValue().next = map.get(entry.getKey().next);
// link random
entry.getValue().random = map.get(entry.getKey().random);
}
return map.get(head);
}
}