题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。
对于复杂链表,一般会在next域的基础上再增加一个random域,这个指针会指向任意节点或者是一个NULL。
在对复杂链表进行复制时,也要对random进行复制,但是,random指针具有随机性,所以我们采用以下方法,
1.首先,在每一个节点后,都插入一个与本节点完全一样的节点,形成一个具有原来链表二倍且每个节点都有双份新链表。但是拷贝节点时并没有将random设置正确的指向,所以通过让拷贝出新节点的ramdom指针指向原链表节点的random指针指向的下一个random节点。
2.现在已经有了一条复制好的链表,但是依旧挂载到原链表上,所以现在需要将拷贝好的链表拆解下来即可。
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if(pHead == nullptr)
{
return nullptr;
}
//拷贝并且插入新节点
RandomListNode* cur = pHead;
while(cur)
{
//新节点
RandomListNode* new_node = new RandomListNode(cur->label);
new_node->label = cur->label;
new_node->next = nullptr;
//插入
RandomListNode* next = cur->next;
cur->next = new_node;
new_node->next = next;
cur = next;
}
//更新新链表的random
cur = pHead;
while(cur)
{
RandomListNode* copy = cur->next;
if(cur->random == nullptr)
{
copy->random = nullptr;
}
else
{
copy->random = cur->random->next;
}
cur = cur->next->next;
}
//将新链表拆解下来
cur = pHead;
//找新链表的头节点
RandomListNode* copylist = cur->next;
RandomListNode* tail = cur->next;
cur->next = copylist->next;
cur = cur->next;
while(cur)
{
RandomListNode* copy = cur->next;
cur->next = copy->next;
//确保原链表的完整性
tail->next = copy;
tail = copy;
cur = cur->next;
}
return copylist;
}
};