题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
思路
因为链表本身的连续性,所以,随机指针只是一个指针,目的是实现一个随机的下一个节点
随机下节点不需要复制。只要复制目的地地址就行了
先遍历一遍,整体复制,将复制节点链接至原节点后面
遍历链表,完成随机指针的赋值,复制随机指针指向复制节点
遍历链表,拆分新旧节点
/*
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 * currNode = pHead;
while (currNode != nullptr) {
RandomListNode *node = new RandomListNode(currNode->label);
node->next = currNode->next;
currNode->next = node;
currNode = node->next;
}
// 遍历一遍,链表随机节点处理,每次移动两个节点
currNode = pHead;
while (currNode != nullptr) {
RandomListNode * node = currNode->next; // 获取当前节点的复制节点
if (currNode->random != nullptr) { // 当前节点有随机下节点,因为,随机下节点是新复制的节点
node->random = currNode->random->next; // 让随机下节点引用指向复制节点
}
currNode = node->next; // 跟新当前节点
}
// 新旧链表拆分,遍历一边,每次移动一个节点,巧妙的拆分复制的节点。
RandomListNode * pCloneHead = pHead->next;
RandomListNode *tmp;
currNode = pHead;
while (currNode->next != nullptr) {
tmp = currNode->next; // 暂时存储引用复制节点
currNode->next = tmp->next; // 截断对复制节点的引用
currNode = tmp; //不仅原节点对复制节点的引用要截断,复制节点对原节点的引用也要截断
}
return pCloneHead;
}
};
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com