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.
Two passes
Time Complexity
O(N)
Space Complexity
O(N)
思路
Two passes, no need to check target node exists or not
First pass: build the hashmap for the relationship from the original node to the new node
代码
public RandomListNode copyRandomList(RandomListNode head) {
//corner case
if(head == null) return null;
Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode,RandomListNode>();
RandomListNode cur = head;
RandomListNode node = new RandomListNode(cur.label);
map.put(cur, node);
cur = cur.next;
//deep copy each node
while(cur != null){
map.put(cur, new RandomListNode(cur.label));
cur = cur.next;
}
cur = head;
while(cur != null){
//connect next node
map.get(cur).next = map.get(cur.next);
//connect random node
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
return node;
}
One pass
Time Complexity
O(N)
Space Complexity
O(N)
思路
Use a dummy node so we can check the first node use the same steps
cur = dummy which is the deep copied linked list
curNext is the original linked list
Step 1: to build a hashmap, for loop make a copy of the linked list with next pointer and random pointer
Step 2: using hashmap to check the random or next pointers exist in the hashmap or not. If exist, get the copied node's reference and assign to random or next
代码
public RandomListNode copyRandomList(RandomListNode head) {
//corer case
if(head == null) return null;
Map<RandomListNode,RandomListNode> map = new HashMap<RandomListNode,RandomListNode>();
RandomListNode dummy = new RandomListNode(0);
dummy.next = head;
//this is the deep copy linkedlist
RandomListNode cur = dummy;
//this is the orginal linkedlist
RandomListNode curNext = head;
while(curNext != null){
if(!map.containsKey(curNext)){
//if there is no node in the copied linked list, create a new node into hashmap
map.put(curNext, new RandomListNode(curNext.label));
}
//now the next node of cur node is created
cur.next = map.get(curNext);
//check if cur has random node
if(curNext.random != null){
//check if the cur.random has been created
if(!map.containsKey(curNext.random)){
map.put(curNext.random, new RandomListNode(curNext.random.label));
}
cur.next.random = map.get(curNext.random);
}
curNext = curNext.next;
cur = cur.next;
}
return dummy.next;
}
Three passes WithOut Extra Space
Time Complexity
O(N)
Space Complexity
O(1)
思路
1 1‘ 2 2’ 3 3‘ 4 4’ 5 5‘
Step1:
Create the copy of the node 1 and insert it between node1 & node2 in original linkedlist, continue the same method until the last node
Step2:
Iterate the new list and assign the random pointer for each,cur.next.random = cur.random.next
Step3:
We can use the method as L328"odd and even linkedlist" odd and even linkedlist answerThe only difference is to add null after the last odd nodes.
I think we need to keep the original linkedlist because it has errors when I just keep the copied linkedlist and it can't pass leetcode
代码
public RandomListNode copyRandomList(RandomListNode head) {
//corner case
if(head == null) return null;
RandomListNode cur = head;
//iterate each original node and deep copy each node then insert the deep copy node after the orginal node
while(cur != null){
RandomListNode newNode = new RandomListNode(cur.label);
newNode.next = cur.next;
cur.next = newNode;
cur = newNode.next;
}
cur = head;
//iterate the new list and assign the random pointer for each node
while(cur != null){
if(cur.random != null){
cur.next.random = cur.random.next;
}
cur = cur.next.next;
}
//partition the original node and the copied node
cur = head;
RandomListNode copyNode = cur.next;
RandomListNode copyNodeHead = copyNode;
while(copyNode != null && copyNode.next != null){
cur.next = copyNode.next;
copyNode.next = copyNode.next.next;
cur = cur.next;
copyNode = copyNode.next;
}
cur.next = null;
return copyNodeHead;
}