题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的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) return nullptr; //链表为空,返回空指针
nodeClone(pHead); //复制结点,插入到原结点后方
connectRandom(pHead); //设置新结点的random指针
return reconnect(pHead); //拆成两个链表
}
//[1]复制结点,插入到原结点后方
void nodeClone(RandomListNode *head)
{
RandomListNode *pNode = head;
while (pNode != nullptr) //当节点不为空时
{
RandomListNode *pClone = new RandomListNode(pNode->label); //复制节点,用原节点的值初始化
pClone->next = pNode->next; //将复制的节点插入到链表中,从后向前链接,复制节点链接后面的节点
pNode->next = pClone; //前面的节点链接复制节点
pNode = pClone->next; //pnode指针向后走
}
}
//[2]设置新结点的random指针,原节点N、S的复制节点为n、s,
//假设原节点N的random指针指向节点S,复制出来的节点n的random指针指向s。
void connectRandom(RandomListNode *head)
{
RandomListNode *pNode = head; //以pnode节点为当前节点
while (pNode != NULL) //当前节点不为空时
{
RandomListNode *pClone = pNode->next; //下一个节点:即为当前节点的复制节点
if (pNode->random) //节点的random指针不为空的话
{
pClone->random = pNode->random->next; //复制节点的random指针指向原节点random指针指向节点的下一个节点
}
pNode = pClone->next; //当前节点向后走
}
}
//[3]把长链表拆分成两个链表,奇数位节点连接起来为原始链表;偶数位置节点连接起来为复制出来的链表
RandomListNode *reconnect(RandomListNode *head)
{
RandomListNode *pNode = head; //以pnode节点为当前节点,始终指向奇数节点
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; //返回偶数节点
}
};