35 复杂链表的复制
题目
请实现函数ComplexListNode Clone(ComplexListNode head),复制一个复杂链表。在复杂链表中,每个结点除了有一个Next指针指向下一个结点外,还有一个Sibling指向链表中的任意结点或者NULL。
下图是一个含有5个结点的复杂链表。图中实线箭头表示m_pNext指针,虚线箭头表示m_pSibling指针。为简单起见,指向NULL的指针没有画出。
C++ 题解
第一步仍然是根据原始链表的每个结点N创建对应的N'。(把N'链接在N的后面);
第二步设置复制出来的结点的Sibling。(把N'的Sibling指向N的Sibling);
第三步把这个长链表拆分成两个链表:把奇数位置的结点用Next链接起来就是原始链表,偶数数值的则是复制链表。
最后,将三个步骤衔接起来形成Clone方法。
/*
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;
RandomListNode* pCurrentNode = pHead;
// 对原链表的每个节点进行克隆,并以此成为原链表节点的后继节点
while(pCurrentNode)
{
RandomListNode* pCloned = new RandomListNode(pCurrentNode->label);
// 此处的交换需要注意顺序,可以画图查看
pCloned->next = pCurrentNode->next;
pCurrentNode->next = pCloned;
pCurrentNode = pCloned->next;
}
// 如果原链表的节点中存在着任意连接,那么也为克隆的节点增加上任意连接
pCurrentNode = pHead;
while(pCurrentNode)
{
if(pCurrentNode->random)
{
pCurrentNode->next->random = pCurrentNode->random->next;
}
//注意:此处,每次跳过两个
pCurrentNode = pCurrentNode->next->next;
}
// 两个链表分离,从新合成的链表中抽出克隆节点
RandomListNode *pCloneHead = pHead->next;
RandomListNode *tmp = pCloneHead;
pCurrentNode = pHead;
while(pCurrentNode->next)
{
tmp = pCurrentNode->next;
pCurrentNode->next = tmp->next;
pCurrentNode = tmp;
}
return pCloneHead;
}
};
python 题解
方法一
递归实现:
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
if pHead==None:
return None
newNode=RandomListNode(pHead.label)
newNode.random=pHead.random
newNode.next=self.Clone(pHead.next)
return newNode