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.
一道相对比较复杂的链表题。第一种思路是使用HashMap来存储原来的节点和新生成的节点之间的对应关系,通过这个对应关系来恢复新生成的节点的random所指向的节点。这种方法的空间复杂度为O(n)。
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null) return head;
HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
RandomListNode dummy = new RandomListNode(0);
RandomListNode temp1 = head, temp2 = dummy;
while(temp1 != null) {
RandomListNode node = new RandomListNode(temp1.label);
map.put(temp1, node);
temp2.next = node;
temp2 = temp2.next;
temp1 = temp1.next;
}
temp1 = head; temp2 = dummy.next;
while(temp1 != null) {
if(temp1.random != null) {
temp2.random = map.get(temp1.random);
}
temp1 = temp1.next;
temp2 = temp2.next;
}
return dummy.next;
}
另一种方法比较巧妙,通过改变原来的链表,即将新生产的节点插入在原来的节点后面,然后第二遍扫描的时候来恢复random的值,然后第三遍扫描将原来的节点和新生产的节点分离,从而得到一个deep copy原来的链表。
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null) return head;
RandomListNode temp = head;
while(temp != null) {
RandomListNode node = new RandomListNode(temp.label);
node.next = temp.next;
temp.next = node;
temp = node.next;
}
temp = head;
while(temp != null) {
if(temp.random != null) {
temp.next.random = temp.random.next;
}
temp = temp.next.next;
}
RandomListNode nhead = head.next, ntemp = head.next;
temp = head;
while(head != null) {
temp.next = ntemp.next;
temp = temp.next;
if(temp == null) break;
ntemp.next = temp.next;
ntemp = ntemp.next;
}
return nhead;
}
没有评论:
发表评论