版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Android_chunhui/article/details/88812529
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
思路:
难点主要是random节点的复制,原链表中random节点有两种:为NULL;存在。思路是1.在原链表每个节点后面复制节点;2.处理random节点;3.拆分节点(一定注意原链表连接关系的回复)。一定要画图!!!
class Solution {
public:
void insert(RandomListNode* pHead)
{
RandomListNode *pNode = pHead;
while (pNode)
{
RandomListNode *p = new RandomListNode(pNode->label);
p->next = pNode->next;
pNode->next = p;
pNode = p->next;
}
}
void deal_random(RandomListNode* pHead)
{
//新链表的random也就是对应原链表节点的random的下一个节点。
RandomListNode *pNode = pHead;
while (pNode)
{
RandomListNode *p = pNode->next;
if(pNode->random)
p->random = pNode->random->next;
pNode = p->next;
}
}
RandomListNode* split(RandomListNode* pHead)
{
RandomListNode *head = NULL, *p = NULL;
RandomListNode *pNode = pHead;
if (pNode)
{
head = p = pNode->next;
pNode->next = p->next;
pNode = p->next;//一定要注意原链表连接关系的恢复。
}
while (pNode)
{
p->next = pNode->next;
p = p->next;
pNode->next = p->next;
pNode = p->next;
}
return head;
}
RandomListNode* Clone(RandomListNode* pHead)
{
insert(pHead);
deal_random(pHead);
return split(pHead);
}
};
当然也有直接新建一个链表的,那样就省拆分这一步骤。注意用hash保存原链表节点与新链表节点的对应关系,否则无法对应random节点。注意源节点的random可能是空的,之前没有注意到这一点报错。
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
map< RandomListNode*, RandomListNode*> record;
//尾插法
RandomListNode *pNode = pHead;
RandomListNode *head = NULL, *tail = NULL;
if (pNode)
{
head = new RandomListNode(pNode->label);
tail = head;
record[pNode] = tail;
pNode = pNode->next;
}
while (pNode)
{
RandomListNode *p = new RandomListNode(pNode->label);
tail->next = p;
tail = p;
record[pNode] = p;
pNode = pNode->next;
}
//处理random节点
pNode = pHead;
tail = head;
while (pNode)
{
if (pNode->random)
{//一定要判断random是否为空
if (record.find(pNode->random) == record.end())
{
RandomListNode *p = new RandomListNode(pNode->random->label);
tail->random = p;
}
else
tail->random = record[pNode->random];
}
tail = tail->next;
pNode = pNode->next;
}
return head;
}
};