《剑指offer》复杂链表的复制

【 声明:版权所有,转载请标明出处,请勿用于商业用途。  联系信箱:libin493073668@sina.com】


题目链接:http://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking


题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。

思路

第一步我们首先对每个结点进行复制,并让复制的结点链接在原结点的后面,先使其成为一条完整的链,如下所示

A->A'->B->B'->C->C'

第二步我们就可以来拷贝其random指针了,我们知道原链结点和复制链的结点是间隔排布的,那么我们很容易找到其对应的关系,因为A'的位置是A->next,假设A->random=C,那么也就可以得出A'->RANDOM=C->next=A->random->next

第三步,由于此时我们已经完成了拷贝,我们所需要的就是将拷贝链提取出来,那么我们使用两个指针间隔移动即可


/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution
{
	public:
		RandomListNode* Clone(RandomListNode* pHead)
		{
			CloneNode(pHead);
			CloneRandom(pHead);
			return ReconnectNode(pHead);
		}
		void CloneNode(RandomListNode* head)
		{
			RandomListNode* pNode = head;
			while(pNode!=nullptr)
			{
				RandomListNode* pClone = new RandomListNode(0);
				pClone->label = pNode->label;
				pClone->next = pNode->next;
				pNode->next = pClone;
				pNode = pClone->next;
			}
		}
		void CloneRandom(RandomListNode* head)
		{
			RandomListNode* pNode = head;
			while(pNode!=nullptr)
			{
				RandomListNode* pClone = pNode->next;
				if(pNode->random!=nullptr)
				{
					pClone->random = pNode->random->next;
				}
				pNode = pClone->next;
			}
		}
		RandomListNode* ReconnectNode(RandomListNode* head)
		{
			RandomListNode* pNode = head;
			RandomListNode* pCloneHead = nullptr;
			RandomListNode* pCloneNode = nullptr;
			if(pNode!=nullptr)
			{
				pCloneHead = pCloneNode = pNode->next;
				pNode->next = pCloneNode->next;
				pNode = pNode->next;
			}
			while(pNode!=nullptr)
			{
				pCloneNode->next = pNode->next;
				pCloneNode = pCloneNode->next;
				pNode->next = pCloneNode->next;
				pNode = pNode->next;
			}
			return pCloneHead;
		}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值