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.
Solution1:HashMap的方法
/**
* 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 {
public RandomListNode copyRandomList(RandomListNode head) {
if(head==null) return null;
Map<RandomListNode, RandomListNode> amap = new HashMap<RandomListNode, RandomListNode>();
RandomListNode newHead = new RandomListNode(head.label);
RandomListNode cur=newHead, oldCur=head;
amap.put(oldCur,cur);
while(oldCur.next!=null){
oldCur=oldCur.next;
RandomListNode next=new RandomListNode(oldCur.label);
cur.next=next;
cur=cur.next;
amap.put(oldCur,cur);
}
cur.next=null;
cur=newHead;
oldCur=head;
while(cur!=null){
RandomListNode random = oldCur.random;
if(random==null) cur.random=null;
else{
random = amap.get(random);
cur.random = random;
}
cur=cur.next;
oldCur=oldCur.next;
}
return newHead;
}
}第一遍遍历list并创建hashmap中相应key-value pair用了O(n),第二遍查找hashmap得到random的值,用了O(n),最后时间复杂度为O(n), 空间复杂度O(n)。
Solution2:Node-attached-as-next-node方法。没新建一个new list中的节点,就将其插入原节点与原节点的next之间。这样每个新节点的random值可以通过原节点的random的next获得。这种方法优点在于不用建立hashmap,只需建立新的list,节省了空间。缺点是在做deep copy的过程中需要改变原list,不是很安全。
/**
* 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 {
public RandomListNode copyRandomList(RandomListNode head) {
if(head==null) return null;
RandomListNode oldPtr =head, newPtr=null;
//build new list, change the structure of the old list
while(oldPtr!=null){
newPtr = new RandomListNode(oldPtr.label);
newPtr.next = oldPtr.next;
oldPtr.next=newPtr;
oldPtr = oldPtr.next.next;
}
oldPtr=head;
RandomListNode newHead = oldPtr.next;
//set the random pointer for new list
while(oldPtr!=null){
if(oldPtr.random!=null)
oldPtr.next.random = oldPtr.random.next;
oldPtr=oldPtr.next.next;
}
//recover the old list, correct the new list
oldPtr=head;
newPtr=newHead;
while(oldPtr!=null){
newPtr=oldPtr.next;
oldPtr.next=oldPtr.next.next;
if(newPtr.next!=null) newPtr.next=newPtr.next.next;
oldPtr=oldPtr.next;
}
return newHead;
}
}

本文介绍两种深拷贝含额外随机指针的链表方法:使用HashMap存储对应关系及在原节点后直接插入新节点的方式。第一种方法时间复杂度O(n),空间复杂度O(n);第二种方法虽改变原链表结构但不使用额外空间。

被折叠的 条评论
为什么被折叠?



