Copy List with Random Pointer
Description
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.
Challenge
Could you solve it with O(1) space?
实现思路一:基于哈希表
常规思路是我们可以维护一个哈希表,需要额外O(n)的空间复杂度。
每次复制的时候,将其随机节点作为键存到hash表中,值为新复制的节点。
如此循环一遍后,我们得到个依次连接的新的链表,同时一个对应的哈希表。
第二次同时对新旧链表进行遍历,每次以旧链表节点的随机节点(如果不存在,则不做任何操作)作为健,查找哈希表对应的的值(新链表节点),作为当前遍历到的新链表节点的随机节点。
根据此思路,求解方法如下:
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
/**
* @param head: The head of linked list with a random pointer.
* @return: A new head of a deep copy of the list.
*/
public RandomListNode copyRandomList(RandomListNode head) {
// write your code here
if(head == null){
return null;
}
HashMap<RandomListNode,RandomListNode> map = new HashMap<>();
RandomListNode behead = head,newhead = new RandomListNode(-1),benewhead = newhead;
while(head != null){
RandomListNode newNode = new RandomListNode(head.label);
newhead.next = newNode;
newhead = newhead.next;
map.put(head,newhead);
head = head.next;
}
head = behead;
newhead = benewhead.next;
while(head != null){
if(head.random != null){
newhead.random = map.get(head.random);
}
head = head.next;
newhead = newhead.next;
}
return benewhead.next;
}
}
实现思路二:基于复制链表
思路一我们使用了额外的哈希表来存储映射关系,但利用相似的思路,结合链表的特性,我们可以去掉哈希表,将哈希表中oldnode->newnode的映射直接放到链表中。
假设原来节点为:
oldnode1->oldnode2->oldnode3->oldnde4
现在变成
oldnode1->newnode1->oldnode2->newnde2->oldnode4->newnode3->oldnode5->newnde4
当需要设置随机节点时,我们只需利用类似于哈希表的思路:newnode.random = map.get(head.random)
对于到这个新的“融合链表”中,就是:
oldnode.next.random = oldnode.random.next
这里注意做恒等比较,即:
1. oldnode.next(.random) = newnode(.random)
2. map.get(oldnode.random) = oldnode.random.next
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
/**
* @param head: The head of linked list with a random pointer.
* @return: A new head of a deep copy of the list.
*/
public RandomListNode copyRandomList(RandomListNode head) {
// write your code here
if(head == null){
return null;
}
RandomListNode behead = head;
while(head != null){
RandomListNode newNode = new RandomListNode(head.label);
newNode.next = head.next;
head.next = newNode;
head = newNode.next;
}
head = behead;
while(head != null){
if(head.random != null){
head.next.random = head.random.next;
}
head = head.next.next;
}
head = behead.next;
while(head.next != null){
head.next = head.next.next;
head = head.next;
}
return behead.next;
}
}