题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路
自己的思路和官方的思路:
自己的思路:
- 按照原链表赋值出一份新的链表,但不复制random指针。
- 按照原链表遍历的方式,对新链表添加random指针。
官方思路:
- 在原链表的基础上,每个结点后面均复制新的结点。
- 原链表遍历,同时给复制结点添加random指针。
- 原链表与新链表拆分。
代码实现
- 自己思路:
又犯了很低级错误,在牛客网的剑指offer平台上,因为一个英文的逗号写成了中文逗号,检查了很长时间, 下次将for循环中的逗号,改成 && 这样 是可以的。
/*
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 == NULL)
return NULL;
RandomListNode* pHeadNew = CopyLinkList(pHead);
InsertRandomPointer(pHead, pHeadNew);
return pHeadNew;
}
RandomListNode* CopyLinkList(RandomListNode* &pHead)
{ // 与头插法混淆 这是复制链表
if(pHead == NULL)
return NULL;
RandomListNode* p = pHead;
RandomListNode* pHeadNew = NULL; // 新链表的头结点
RandomListNode* pHeadNewTemp = pHeadNew, *p2 = pHeadNew;
for(; p; p = p->next)
{
pHeadNewTemp = new RandomListNode(p->label);
if(pHeadNew)
{
p2->next = pHeadNewTemp;
p2 = pHeadNewTemp;
}
else
{
pHeadNew = pHeadNewTemp;
p2 = pHeadNewTemp;
}
}
return pHeadNew;
}
void InsertRandomPointer(RandomListNode* &pHead, RandomListNode* &pHeadNew)
{
if(pHead == NULL || pHeadNew == NULL)
return;
RandomListNode* pHeadtemp = pHead, *pHeadNewtemp = pHeadNew;
for(; pHeadtemp, pHeadNewtemp; pHeadtemp = pHeadtemp->next, pHeadNewtemp = pHeadNewtemp->next)
{
if(pHeadtemp->random)
{
RandomListNode* pHeadSearch = pHead, *pHeadNewSearch = pHeadNew;
for(; pHeadSearch && pHeadNewSearch; pHeadSearch = pHeadSearch->next, pHeadNewSearch = pHeadNewSearch->next)
//英文逗号 与 中文逗号 太相似
if(pHeadSearch == pHeadtemp->random)
{
pHeadNewtemp->random = pHeadNewSearch;
break;
}
}
}
}
};
- 官方思路解法:
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if(pHead == NULL)
return NULL;
NewNodeCopy(pHead);
InsertRandomPointer(pHead);
return GetNewRandomList(pHead);
}
void NewNodeCopy(RandomListNode* &pHead)
{
if(pHead == NULL)
return;
RandomListNode* pTemp = pHead, *pNewNode = NULL;
while(pTemp)
{
pNewNode = new RandomListNode(pTemp->label);
pNewNode->next = pTemp->next;
pTemp->next = pNewNode;
pTemp = pNewNode->next;
}
}
void InsertRandomPointer(RandomListNode* &pHead)
{
if(pHead == NULL)
return;
RandomListNode* pTemp = pHead, *pNewTemp = pHead->next;
while(pTemp)
{
if(pTemp->random)
pNewTemp->random = pTemp->random->next;
pTemp = pNewTemp->next;
pNewTemp = pTemp->next;
}
}
RandomListNode *GetNewRandomList(RandomListNode *head)
{
RandomListNode *pNode = head;
RandomListNode *result = head->next;
while (pNode != NULL)
{
RandomListNode *pClone = pNode->next;
pNode->next = pClone->next;
pNode = pNode->next;
if (pNode != NULL)
pClone->next = pNode->next;
}
return result;
}
};