码迷,mamicode.com
首页 > 其他好文 > 详细

【leetcode】Copy List with Random Pointer

时间:2014-05-19 15:50:28      阅读:447      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   code   c   java   

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.


 

好麻烦的链表题T_T

首先说一下深拷贝和浅拷贝的区别,参考这篇博文:http://www.cnblogs.com/BlueTzar/articles/1223313.html

深拷贝:在拷贝过程中,为新的变量申请新的空间,所以原来的变量不存在时,拷贝得到的变量还可以使用。

浅拷贝:在拷贝过程中,不为新变量申请新的空间,只是把原来变量的地址给新的变量,原来的变量不存在时,拷贝得到变量也不能使用了。

所以在题目中,要做到两点,第一原来的链表不能改变;第二,拷贝得到的链表要有自己完全独立的内存空间,而不是只是指向原来的链表。


 

解题思路思路参考:http://www.cnblogs.com/lautsie/p/3259724.html

但是这个博客有个bug,就是恢复原来链表的next指针和建立新链表的random和next指针是不能同时进行的。因为有可能有如下情况:

bubuko.com,布布扣

在建立3‘的random指针的时候通过3‘当前的random指针找到3,又通过3的random指针找到1,但是如果1的next指针已经被改为指向2,而不再是1‘,那么就没办法找到3‘真正的random指针1‘了,所以恢复原来链表的next指针,只能在新链表完全建立好以后进行。那么就需要一个结构来存储原来链表的next指针信息,这里采用一个map:oldlistnext保存。

所以算法分为3个循环:

第一个循环,建立新的链表,并且把新链表中各个节点的random指针指向原来链表对应的节点,原来链表的next指针指向新链表的对应节点,如下图所示:

bubuko.com,布布扣

图中橙色是原来链表的next指针,绿色是新建链表的random指针,蓝色虚线表示新建链表的next指针。

第二个循环,恢复新建链表的next和random指针:new_list_p->next = new_list_p->next->next;new_list_p->random = new_list_p->random->random->next;如下图所示:

bubuko.com,布布扣

第三个循环,恢复原来链表的next指针,old_list_p->next = oldlistnext[old_list_p],如下图所示:

bubuko.com,布布扣

当然,上述过程中要注意各种边界情况的考虑。

代码如下:

bubuko.com,布布扣
 1 class Solution {
 2 public:
 3     RandomListNode *copyRandomList(RandomListNode *head) {
 4         if(head == NULL)
 5             return NULL;
 6 
 7         RandomListNode* old_list_p = head;
 8         RandomListNode* new_list_p;
 9         bool has_head = 0;
10         std::map<RandomListNode *,RandomListNode *> oldlistnext;
11 
12         //建立新的链表
13         while(old_list_p != NULL){
14             RandomListNode* temp= (struct RandomListNode*)malloc(sizeof(struct RandomListNode));
15             if(has_head == 0){
16                 new_list_p = temp;
17                 has_head = 1;
18             }
19             oldlistnext.insert(std::map<RandomListNode*,RandomListNode*>::value_type(old_list_p, old_list_p->next));
20 
21             temp->label = old_list_p->label;
22             temp->next = old_list_p->next;
23             temp->random = old_list_p;
24             old_list_p->next = temp;
25 
26             old_list_p = temp->next;
27         }
28 
29         RandomListNode* h = new_list_p;
30         old_list_p = head;
31 
32         //恢复新建链表的next和random指针
33         while(new_list_p != NULL){
34             if(new_list_p->random->random != NULL){
35                 new_list_p->random = new_list_p->random->random->next;
36             }
37             else
38                 new_list_p->random = NULL;
39 
40             if(new_list_p->next != NULL)
41                 new_list_p->next = new_list_p->next->next;
42             else
43                 new_list_p->next = NULL;
44 
45             new_list_p = new_list_p->next;
46 
47         }
48 
49         old_list_p = head;
50         
51         //恢复原来链表的next指针
52         for(int i = 1;i <= oldlistnext.size();i++){
53             old_list_p->next = oldlistnext[old_list_p];
54             old_list_p = old_list_p->next;
55         }
56 
57         return h;
58     }
59 };
bubuko.com,布布扣

 

 

【leetcode】Copy List with Random Pointer,布布扣,bubuko.com

【leetcode】Copy List with Random Pointer

标签:style   blog   class   code   c   java   

原文地址:http://www.cnblogs.com/sunshineatnoon/p/3735094.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!