问题
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
思路:
1.定义一个cur指针指向链表的头结点,创建一个结点和它指向的结点内容一样,并且连接在它和它的下一个结点之间,如图所示:
2.处理复杂结点的random指针: 由上图可以知道:使复制结点的random指向原来结点random指向的结点的下一个结点,但是当原来结点的random指向NULL时候,复制结点的random直接指向NULL即可。
3.恢复链表:将cur从头开始迭代,创建一个next指针指向复制结点的下一个结点,以免一会找不到了,令cur的next指向next,复制结点的next指向next的next,然后令cur = next,继续迭代。
最后返回复制结点的头结点,你可以发现好像找不到它了,所以在第一步后可以创建一个指针保存它的头结点。
一般情况如图序号一,特殊情况如图序号二。
代码展示:
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) {
if(head == NULL){
return NULL;
}
//思路1.定义一个cur指针指向链表的头结点,创建一个结点和它指向的结点内容一样,
//并且连接在它和它的下一个结点之间
Node* cur = head;
while(cur){
//复制cur
Node* copy = (Node*)malloc(sizeof(Node));
copy->random = NULL;
copy->val = cur->val;
//copy连接在cur后面
copy->next = cur->next;
cur->next = copy;
//迭代
cur = copy->next;
}
//提前保存复制链表的头防止丢失
Node* copyHead = head->next;
//将cur置回head
cur = head;
//思路2.处理复制结点的random指针
while(cur){
Node* copy = cur->next;
//特殊处理原结点random指向NULL情况
if(cur->random == NULL){
copy->random = NULL;
}
//处理一般情况
else{
copy->random = cur->random->next;
}
//继续迭代
cur = copy->next;
}
//思路3.恢复链表
cur = head;
while(cur){
Node* copy = cur->next;
Node* next = copy->next;
//处理next为空的特殊情况
if(next == NULL){
cur->next = NULL;
}
//处理一般情况
else{
cur->next = copy->next;
copy->next = next->next;
}
//继续迭代
cur = next;
}
return copyHead;
}