leetcode Copy List with Random Pointer

来源:互联网 发布:淘宝装修外包 编辑:程序博客网 时间:2024/06/05 10:52


此题要求深拷贝链表,该链表中每个结点额外增加了一个random指针,该random指针或为NULL或指向任意一个结点。


深拷贝&浅拷贝

CSDN中较为通俗易懂的比喻:

老师给你们留了作业,你们班只有小明一个人做了,其他人都需要copy他的作业,如果你们都是通过浅拷贝来完成作业,那么就相当与“在你需要的时候,小明会把作业借给你”。

例如:老师要检查小红的作业,小红就去把小明的作业带给老师看,轮到小虎时,小虎就再向小明借。但如果说”把你们的作业全部交上来“,那么你们就完蛋了。

深拷贝就是每个人都实实在在的抄了一份作业,即使老师最后要求大家一起交上去也没有问题。


如果要对一个链表进行深拷贝,则需要创建这个链表中的所有表结点对象,再将这些对象按照原来的关系链接起来,这时存在两条链表,内存中增加了一倍的存储(增加了n个对象引用,以及为这些对象分配的n个空间)。

若为浅拷贝,只是拷贝了一个链表对象引用,并为这个引用分配了相应的空间,内存中仅仅是多了一个对象的引用(4个字节,栈区分配)以及一个对象(堆区分配)。


此题的难点在于节点中的random指针,因为深拷贝是重新开辟的空间,所以,random指针的赋值是一个较大的问题。

下面链接是youku上讲解深拷贝链表的视频,很不错。

http://v.youku.com/v_show/id_XNjU1NzI0NDAw.html


具体思路:

1,在原链表中每个结点的后面copy一个新结点,random先不做处理

2,根据原理可知新建结点的random指针与原结点random指针的关系 ,即:new->random = old->random->next

3,依次拆分链表得到原链表和深拷贝后得到的新链表

如图(图片来自http://www.cnblogs.com/TenosDoIt/p/3387000.html)


代码如下:

class Solution{public:RandomListNode *copyRandomList(RandomListNode *head){RandomListNode *p, *temp, *copyHead;p = head;if(head == NULL)return head;//遍历第一遍copy结点while(p!=NULL){temp = new RandomListNode(p->label);temp->next = p->next;p->next = temp;p = p->next->next;}//遍历第二遍为random赋值p = head;while(p!=NULL){RandomListNode *q = p->next;if(p->random == NULL)q->random = NULL;elseq->random = p->random->next;p = p->next->next;}//遍历第三遍拆分链表p = head;copyHead = new RandomListNode(0);temp = copyHead;while(p!=NULL){temp->next = p->next;temp = temp->next;p->next = p->next->next;p = p->next;}return copyHead->next;}};


0 0