138. Copy List with Random Pointer (Medium)
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.
class RandomListNode {
int label;
RandomListNode next, random;
RandomListNode(int x) {
this.label = x;
}
}
Solution 1: One-pass with dummy node O(n); O(1)
/**
* One-pass with dummy node O(n);O(1)
* Create a dummy node and a current pointer of copy list start from dummy.
* Use another pointer to traverse the input linked list.
* Each time, copy current node and the random of current node.
* Then move current pointer of copy list and input list to next respectively.
*/
public RandomListNode copyRandomListC(RandomListNode head) {
RandomListNode dummy = new RandomListNode(0);
RandomListNode curCopy = dummy;
RandomListNode cur = head;
while (cur != null) {
RandomListNode copy = new RandomListNode(cur.label);
copy.random = cur.random == null ? null : new RandomListNode(cur.random.label);
curCopy.next = copy;
curCopy = curCopy.next;
cur = cur.next;
}
return dummy.next;
}
Solution 2: Three-pass O(n); O(1)
/**
* Three-pass O(n); O(1)
* 1.copy each node,and link them together side-by-side in a single list
* 2.copy random pointers for the copy nodes
* 3.restore the original list, and extract the copy list
*/
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) {
return null;
}
RandomListNode n = head;
while (n != null) {
//should be n != null, otherwise, if n.next == null, the node n will not be copied.
RandomListNode next = n.next;
n.next = new RandomListNode(n.label);
n.next.next = next;
n = next;
}
n = head;
while (n != null) {
if (n.next != null) {
n.next.random = n.random.next;
}
n = n.next.next;
}
n = head;
RandomListNode copyHead = head.next;
RandomListNode copy = copyHead;
while (copy.next != null) {
n.next = n.next.next;
n = n.next;
copy.next = copy.next.next;
copy = copy.next;
}
n.next = null;
return copyHead;
}