请实现一个函数可以复制一个复杂链表。
在复杂链表中,每个结点除了有一个指针指向下一个结点外,还有一个额外的指针指向链表中的任意结点或者null。
注意:
- 函数结束后原链表要与输入时保持一致。
数据范围
链表长度 [0,500]。
/**
* Definition for singly-linked list with a random pointer.
* struct ListNode {
* int val;
* ListNode *next, *random;
* ListNode(int x) : val(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:
//题意是复制一个链表,并且实现多一个rondom指针。
//本题思路是先在每两个相邻节点之间加一个前节点的复制节点,然后再让复制节点的random指针指向所复制节点的random指针的next节点
//再创建一个虚拟头结点,然后把所有复制节点连上,构成一个链表即可
//还要注意题意要求函数结束后不能修改原链表,所以第37行代码得那样写。就是函数结束后,原链表还是原链表
ListNode *copyRandomList(ListNode *head) {
for(auto p=head;p;)
{
auto np=new ListNode(p->val); //np为新建的复制节点,以下的代码是让np插入p和P->next之间。
auto next=p->next;
p->next=np;
np->next=next;
p=next;
}
for(auto p=head;p;p=p->next->next) //注意更新p是p->next->next;
{
if(p->random)
{
p->next->random=p->random->next;//该操作是让复制节点的random指针指向其所复制的节点的random节点的next节点。
}
}
auto dummy=new ListNode(-1);// 创建一个虚拟头结点,剑指特点,减少代码量
auto cur=dummy;
for(auto p=head;p;p=p->next->next)
{
cur->next=p->next;
cur=cur->next;
p->next=p->next->next;//该行是还原,使原链表的节点的next指针还是指向原下一个节点,而不是复制节点。
}
return dummy->next;
}
};