题目
给你一个长度为n的链表,每个节点包含一个额外增加的随机指针random,该指针可以指向链表中的任何节点或空节点。
构造这个链表的深拷贝。深拷贝应该正好由n个全新节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的next指针和random指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
题解
解题步骤分为三步,首先将原链表的所有结点拷贝一份,并插入在对应的原结点后面。
其次,修改拷贝结点的random指针。从途中可以看出,当结点的random指针不为空时,拷贝结点的random指针指向对应原结点的random指针指向的结点的next,即copy->random = cur->random->next。
最后,将拷贝结点进行尾插,得到深拷贝链表,然后恢复原链表,断开拷贝结点和原链表的链接。
代码如下:
struct Node* copyRandomList(struct Node* head) { //1拷贝结点插在原结点后面 struct Node* cur = head; while (cur) { struct Node* copy = (struct Node*)malloc(sizeof(struct Node)); copy->val = cur->val; struct Node* next = cur->next; cur->next = copy; copy->next = next; cur = next; } //2修改拷贝结点的random指针 cur = head; while (cur) { struct Node* copy = cur->next; struct Node* next = copy->next; if (cur->random == NULL) copy->random = NULL; else copy->random = cur->random->next; cur = next; } //3修改拷贝链表的next指针(尾插法),恢复原链表 cur = head; struct Node* copyHead = NULL; struct Node* copyTail = NULL; while (cur) { //尾插 struct Node* copy = cur->next; struct Node* next = copy->next; if (copyTail == NULL) copyHead = copyTail = copy; else { copyTail->next = copy; copyTail = copyTail->next; } //恢复原链表 cur->next = next; cur = next; } return copyHead; }