剑指offer-- 复杂链表复制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Android_chunhui/article/details/88812529

题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

思路:
难点主要是random节点的复制,原链表中random节点有两种:为NULL;存在。思路是1.在原链表每个节点后面复制节点;2.处理random节点;3.拆分节点(一定注意原链表连接关系的回复)。一定要画图!!!
在这里插入图片描述

class Solution {
public:
	void insert(RandomListNode* pHead)
	{
		RandomListNode *pNode = pHead;
		while (pNode)
		{
			RandomListNode *p = new RandomListNode(pNode->label);
			p->next = pNode->next;
			pNode->next = p;
			pNode = p->next;
		}
	}

	void deal_random(RandomListNode* pHead)
	{
		//新链表的random也就是对应原链表节点的random的下一个节点。
		RandomListNode *pNode = pHead;
		while (pNode)
		{
			RandomListNode *p = pNode->next;
			if(pNode->random)
				p->random = pNode->random->next;
			pNode = p->next;
		}
	}

	RandomListNode* split(RandomListNode* pHead)
	{
		RandomListNode *head = NULL, *p = NULL;
		RandomListNode *pNode = pHead;

		if (pNode)
		{
			head = p = pNode->next;
			pNode->next = p->next;
			pNode = p->next;//一定要注意原链表连接关系的恢复。
		}
		while (pNode)
		{
			p->next = pNode->next;
			p = p->next;
			pNode->next = p->next;
			pNode = p->next;
		}
		return head;
	}
	RandomListNode* Clone(RandomListNode* pHead)
	{
		insert(pHead);
		deal_random(pHead);
		return split(pHead);
	}
};

当然也有直接新建一个链表的,那样就省拆分这一步骤。注意用hash保存原链表节点与新链表节点的对应关系,否则无法对应random节点。注意源节点的random可能是空的,之前没有注意到这一点报错。

class Solution {
public:
	
	RandomListNode* Clone(RandomListNode* pHead)
	{
		map< RandomListNode*, RandomListNode*> record;
		//尾插法
		RandomListNode *pNode = pHead;
		RandomListNode *head = NULL, *tail = NULL;
		if (pNode)
		{
			head = new RandomListNode(pNode->label);
			tail = head;
			record[pNode] = tail;
			pNode = pNode->next;
		}
		while (pNode)
		{
			RandomListNode *p = new RandomListNode(pNode->label);
			tail->next = p;
			tail = p;
			record[pNode] = p;
			pNode = pNode->next;
		}
		//处理random节点
		pNode = pHead;
		tail = head;
		while (pNode)
		{
			if (pNode->random)
			{//一定要判断random是否为空
				if (record.find(pNode->random) == record.end())
				{
					RandomListNode *p = new RandomListNode(pNode->random->label);
					tail->random = p;
				}
				else
					tail->random = record[pNode->random];
			}
			tail = tail->next;
			pNode = pNode->next;
		}
		return head;
	}
};

猜你喜欢

转载自blog.csdn.net/Android_chunhui/article/details/88812529
今日推荐