题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
特殊输入判断测试很重要啊!!!特别是参数为指针,要解决如果为nullptr的情况
方法一:哈希表法,重点在于这个 哈希表的创建
/*
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* pCloned = new RandomListNode(pHead->label);
unordered_map<RandomListNode*, RandomListNode*> table;
table.insert(make_pair(pHead, pCloned));
RandomListNode* pNode1 = pHead->next;
RandomListNode* pNode2 = pCloned;
//复制链表,并创建哈希表
while(pNode1 != nullptr){
pNode2->next = new RandomListNode(pNode1->label);
pNode2 = pNode2->next;
table.insert(make_pair(pNode1, pNode2));
pNode1 = pNode1->next;
}
//复制特殊指针random
pNode1 = pHead;
pNode2 = pCloned;
while(pNode1 != nullptr){
if(pNode1->random != nullptr){
pNode2->random = table.find(pNode1->random)->second;
}
pNode1 = pNode1->next;
pNode2 = pNode2->next;
}
return pCloned;
}
};
方法二:分治法,将复杂问题分解,使其简单化
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
//方法二:
//1、复制原始链表的任意节点,并将新节点N'链接到节点N的后面
void CloneNode(RandomListNode* pHead){
RandomListNode *pNode = pHead;
while(pNode != nullptr){
RandomListNode* pCloned = new RandomListNode(pNode->label);
pCloned->next = pNode->next;
pNode->next = pCloned;
pNode = pCloned->next;
}
}
//2、设置复制出来的节点的random
void ConnectRandom(RandomListNode* pHead){
if(pHead == nullptr)
return;
RandomListNode* pNode = pHead;
RandomListNode* pCloned = pHead->next;
while(pNode != nullptr){
if(pNode->random != nullptr){
pCloned->random = pNode->random->next;
}
pNode = pCloned->next;
pCloned = pNode->next;
}
}
//3、把长链表拆分成两个链表
RandomListNode* ReconnectNodes(RandomListNode* pHead){
if(pHead == nullptr)
return nullptr;
RandomListNode* pNode = pHead;
RandomListNode* pCloneHead = pHead->next;
RandomListNode* pCloneNode = pHead->next;
while(pNode != nullptr){
pNode->next = pCloneNode->next;
pNode = pNode->next;
if(pNode != nullptr){
pCloneNode->next = pNode->next;
pCloneNode = pCloneNode->next;
}
}
return pCloneHead;
}
RandomListNode* Clone(RandomListNode* pHead){
CloneNode(pHead);
ConnectRandom(pHead);
return ReconnectNodes(pHead);
}
};