25、复杂链表的复制
题目描述:
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路:
解法1:开辟新空间
class Solution {
public:
// 复制原始链表的人一节点N并且创建新的节点N',再把N'链接到N后面
void CloneNodes(RandomListNode* pHead){
RandomListNode* pNode=pHead;
while(pNode!=NULL){
RandomListNode* pCloned=new RandomListNode(0);
pCloned->label=pNode->label;
pCloned->next=pNode->next;
pCloned->random=NULL;
pNode->next=pCloned;
pNode=pCloned->next;
}
}
//原始链表上的节点N的random指向S,则对应复制节点N'的random指向S的下一个节点
void ConnectRandomNodes(RandomListNode* pHead){
RandomListNode* pNode=pHead;
while(pNode!=NULL){
RandomListNode* pCloned=pNode->next;
if(pNode->random!=NULL)
pCloned->random=pNode->random->next;
//pCloned->random=pNode->random->next;
pNode=pCloned->next;
}
}
//把得到的链表拆成两个链表,奇数位置上节点组成原始链表,偶数位置上的节点组织复制出来
RandomListNode* ReConnectNodes(RandomListNode* pHead)
{
RandomListNode* pNode=pHead;
RandomListNode* pClonedHead=NULL;
RandomListNode* pClonedNode=NULL;
//初始化
if(pNode!=NULL){
pClonedHead=pClonedNode=pNode->next;
pNode->next=pClonedNode->next;
pNode=pNode->next;
}
//循环
while(pNode!=NULL){
pClonedNode->next=pNode->next;
pClonedNode=pClonedNode->next;
pNode->next=pClonedNode->next;
pNode=pNode->next;
}
return pClonedHead;
}
//三步合一
RandomListNode* Clone(RandomListNode* pHead) {
CloneNodes(pHead);
ConnectRandomNodes(pHead);
return ReConnectNodes(pHead);
}
};
解法2:哈希
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if(pHead==nullptr){
return nullptr;
}
std::unordered_map<RandomListNode*,RandomListNode*>hash_map;
for(RandomListNode*p =pHead; p!= nullptr;p=p->next){
hash_map[p]=new RandomListNode(p->label);
}
for(RandomListNode* p=pHead;p!=nullptr;p=p->next){
hash_map[p]->next=hash_map[p->next];
hash_map[p]->random=hash_map[p->random];
}
return hash_map[pHead];
}
};