题目大意:给定一个链表,链表中的每个节点除了含有next指针,还含有一个random指针,该指针指向链表中的任意节点或为NULL。求该链表的深拷贝。
分析:首先,说明一下深拷贝的含义。所谓深拷贝是指对需要拷贝的值,创建一个新的空间来保存这个值,当删除任何一个变量时,不会出错,因为他们的地址不同。进而可以联想到对应的浅拷贝,浅拷贝是指在对象复制时,只是对对象中的数据成员进行简单的复制,默认拷贝构造函数就是采用的浅拷贝,大多数情况下,浅拷贝已经可以很好的工作了,但是一旦对象存在了动态成员,浅拷贝就会出现问题。因为浅拷贝采取的是把一个变量中的数据地址直接赋值给另一个变量,删除其中任何一个变量,另一个变量中就没有了地址数据。(深拷贝和浅拷贝的详细分析参见:http://blog.csdn.net/bluescorpio/article/details/4322682)
深拷贝简单的理解就是创建出来一个值和原对象相同的对象。本题要考虑到random指针,它指向的对象的值也必须不能改变。
1. 在每个节点后插入一个自己的拷贝;
2. 设置新节点的random指针;
3. 将新链表和原始链表分离开来。返回新链表的头指针即可。
Java代码实现:
/**
* 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 res = null;
RandomListNode tmp;
RandomListNode p = head;
while(p != null) { //在每个节点后插入自己的拷贝
RandomListNode node = new RandomListNode(p.label);
tmp = p.next;
p.next = node;
node.next = tmp;
if(res == null) {
res = node;
}
p = tmp;
}
p = head;
while(p != null) { //设置新节点的random指针
tmp = p.next;
if(p.random != null) {
tmp.random = p.random.next;
}
p = tmp.next;
}
p = head;
tmp = res;
while(tmp.next != null) { //分离新链表和原始链表
p.next = tmp.next;
p = p.next;
tmp.next = p.next;
tmp = tmp.next;
}
p.next = null;
return res;
}
}