标签:des style blog color 使用 io 问题 div
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.
思路:本题要求复制链表,因为每个元素存在一个随机指针,所以使问题变得稍微复杂一些。
方法1:首先,遍历链表,复制当前节点,并将当前节点的地址和新节点的地址映射存入map中;然后,再次遍历链表,通过查找map,找到当前节点及其next和random指针对应的新节点的地址,并修改当前节点对应新节点的next和random字段。
1 class Solution { 2 public: 3 RandomListNode *copyRandomList( RandomListNode *head ) { 4 if( !head ) { return 0; } 5 unordered_map<RandomListNode*,RandomListNode*> addrMap; 6 RandomListNode *curr = head; 7 while( curr ) { 8 addrMap[curr] = new RandomListNode( curr->label ); 9 curr = curr->next; 10 } 11 curr = head; 12 while( curr ) { 13 RandomListNode *newCurr = addrMap[curr]; 14 if( curr->next ) { newCurr->next = addrMap[curr->next]; } 15 if( curr->random ) { newCurr->random = addrMap[curr->random]; } 16 curr = curr->next; 17 } 18 return addrMap[head]; 19 } 20 };
上述方法为完成复制,对每个节点可能需要对map进行3次查找。
方法2:与方法1类似,也使用map记录原始节点和新节点的地址映射关系。不同之处在于,第一次遍历时,已经完成了对正常链表的复制,但新节点的random字段与原始节点相同。因此,第二次遍历时,通过查找map修改新节点的random字段。
1 class Solution { 2 public: 3 RandomListNode *copyRandomList( RandomListNode *head ) { 4 if( head == 0 ) { return 0; } 5 map<RandomListNode*,RandomListNode*> addrMap; 6 RandomListNode *newhead = new RandomListNode(head->label), *node = newhead; 7 node->random = head->random; addrMap[head] = node; 8 while( head->next ) { 9 head = head->next; 10 node->next = new RandomListNode(head->label); 11 node = node->next; 12 node->random = head->random; 13 addrMap[head] = node; 14 } 15 node = newhead; 16 while( node ) { 17 if( node->random ) { 18 node->random = addrMap[node->random]; 19 } 20 node = node->next; 21 } 22 return newhead; 23 } 24 };
该方法相比方法1,对每个节点只需要对map进行1次查找。但其第一次遍历的循环体较方法1要复杂。方法1和方法2都需要使用map记录原始节点和新节点的地址映射。
方法3:通过三次遍历,完成复制过程,不需要使用map存储地址映射关系。
第一次遍历,通过将原始节点的random字段指向新节点的地址,同时将其random字段的原始值存储在新节点的label字段中,以实现原始节点和新节点的映射。这使得我们可以通过原始节点的random字段找到其对应的新节点,这与使用map建立地址映射关系作用相同。
第二次遍历,通过上述映射关系,修改新节点的random字段和next字段,使其指向对应的新节点。
第三次遍历,修改新节点的label字段,同时恢复原始节点的random字段。
1 class Solution { 2 public: 3 RandomListNode *copyRandomList( RandomListNode *head ) { 4 if( head == 0 ) { return 0; } 5 RandomListNode *node = head; 6 // first loop: new all nodes. 7 while( node ) { 8 RandomListNode *newNode = new RandomListNode( (int)node->random ); 9 node->random = newNode; 10 node = node->next; 11 } 12 // second loop: assign random and next pointer. 13 node = head; 14 while( node ) { 15 RandomListNode *newNode = node->random; 16 RandomListNode *random = (RandomListNode*)newNode->label; 17 if( random ) { 18 newNode->random = random->random; 19 } 20 if( node->next ) { 21 newNode->next = node->next->random; 22 } 23 node = node->next; 24 } 25 // third loop: recover ramdom pointer and copy label. 26 node = head; 27 RandomListNode *newHead = head->random; 28 while( node ) { 29 RandomListNode *newNode = node->random; 30 node->random = (RandomListNode*)newNode->label; 31 newNode->label = node->label; 32 node = node->next; 33 } 34 return newHead; 35 } 36 };
Copy List with Random Pointer,布布扣,bubuko.com
标签:des style blog color 使用 io 问题 div
原文地址:http://www.cnblogs.com/moderate-fish/p/3906615.html