1.1 题目描述
1.2 解题思路
这道题有不少公司拿来做笔试或者面试题,用来考察求职者的链表掌握程度;
我有两个方法;这里的难就难在随机指针这里,其它的还好复制,深拷贝就是重新开一个新的大小一样的空间,赋予相同的值,用另一个指针维护;
- 先将全部节点一 一复制连接,下一步再开始复制随机指针了,不是真的复制指针,而是要指向相同的链表相对位置的指针,所以需要真的原链表的随机指针指向哪一个位置的节点,我们复制深拷贝的链表就需要随机指针指向相同复制链表的那个位置,每个随机指针指向的位置节点都需要找,效率不高就是了;
- 复制每一个节点放在每个节点的后面,确保每个深拷贝节点前面一个节点就是原节点;然后是找随机节点指针了,现在有了上面的特性就很好找随机指针了,因为复制节点的随机指针指向的节点就在原链表随机指针节点的后面一个,理解这个点很重要!!!,然后全部随机节点都安排好了以后,把复制链表节点一个一个取下来链接,不要忘了原链表要恢复连接!!!
我这里就不实现第一种方法了,我就实现第二种方法,毕竟第二种方法比较难想到;
1.3 代码实现
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
struct Node* copyRandomList(struct Node* head) {
if(head==NULL)
return NULL;
struct Node* cur=head,*copy=NULL,*next=NULL;
while(cur){//链接深拷贝节点到每个原节点的后面;
next=cur->next;
copy=(struct Node*)malloc(sizeof(struct Node));
copy->val=cur->val;
cur->next=copy;
copy->next=next;
cur=next;
}
cur=head;
while(cur){//更新random
copy=cur->next;
next=copy->next;
if(cur->random==NULL)
copy->random=NULL;
else{
copy->random=cur->random->next;
}
cur=next;
}
cur=head;
struct Node* phead=NULL,*tail=NULL;
while(cur){
//取下深拷贝节点进行链接,恢复原节点
copy=cur->next;
next=copy->next;
if(tail==NULL){
phead=tail=copy;
}
else{
tail->next=copy;
tail=tail->next;
}
cur->next=next;
cur=next;
}
return phead;
}