题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
分析
新建一个复杂链表,新建结点,将原复杂链表中结点原始值及地址赋值给新结点,这样不对,用的还是原链表的内存地址,新分配的内存空间没有用到,
RandomListNode* n = pHead;
RandomListNode* *r = NULL;
while(n){
RandomListNode* body = new RandomListNode(n->label);
body->next = n->next;
body->random = n->random;//把原链表地址赋值给新的链表结点,但使用内存还原链表的,有问题
思路
参考牛客网
step1 使用想复杂链表里插入结点方式,如向结点A后插入结点A1,结点B后插入B1....
将结点A元素值复制给A1
RandomListNode* node = pHead;
while(node){
//设第一个结点为A
RandomListNode* nodeA1 = node;
//将结点A元素值复制给新结点A1
nodeA1->label = nodeA->label;
//将结点A的next指针值赋值给结点A1
nodeA1->next = nodeA->next;
//将结点A的next指针指向结点A1
nodeA->next = nodeA1;
//原链表node的next指向A1,需更新node的值
node = nodeA1->next;
}
step2 在1将复杂链表结点后均插入与其相同的结点并更新next指针域,接下来需要考虑random指针域;
由示意图知,A->random = B; C->random = B; A1->random = B1; C1->random = B1;
B->next = B1;C->next = C1;
新插入结点的random指针域指向结点,为原结点的random的next指针域;
A1->random = A->random ->next;
currNode = pHead;
while(currNode){
RandomListNode *node = currNode->next;
if(currNode->random){
node->random = currNode->random->next;
}
currNode = node->next;
}
step3 将插的结点拆分出来构成一个单独的链表
RandomListNode *pCloneHead = pHead->next;
RandomListNode *tmp;
currNode = pHead;
while(currNode->next){
设定变量实现currNodecurrNode->next -->currNode=currNode->next->next
tmp = currNode->next;
currNode->next = tmp->next;
更新遍历结点位置
currNode = tmp;
}
return pCloneHead ;
参考代码
class Solution{
public:
RandomListNode *Clone(RandomListNode* pHead)
{
if(!pHead) return NULL;
RandomListNode *currNode = pHead;//将链表头结点地址赋值currNode用做遍历链表
while(currNode){
RandomListNode *node = new RandomListNode(currNode->label);//分配内存空间
node->next = currNode->next; //currNode 指针指向下一节点地址赋值给node
currNode->next = node; //把node的值赋给 currNode->next?
currNode = node->next;
}
currNode = pHead;
while(currNode){
RandomListNode *node = currNode->next;
if(currNode->random){
node->random = currNode->random->next;
}
currNode = node->next;
}
//拆分
RandomListNode *pCloneHead = pHead->next;
RandomListNode *tmp;
currNode = pHead;
while(currNode->next){
tmp = currNode->next;
currNode->next = tmp->next;
currNode = tmp;
}
return pCloneHead;
}
};