剑指offer-复杂链表的复制

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),
请对此链表进行深拷贝,并返回拷贝后的头结点。
(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

C++代码

RandomListNode* Clone(RandomListNode* pHead) {
	//方法一:遍历两次链表,用map缓存遍历的每个结点
#if 0
	unordered_map<RandomListNode*, RandomListNode* >mymap;
	//在第一次遍历给定链表的时候,需要复制每个结点值新建结点,
	//用map保存新建结点和旧结点成一个键值对
	RandomListNode* work = pHead;
	//注意输入链表为NULL的特殊情况
	if (work == NULL)
		mymap.insert({ pHead ,NULL });
	while (work != NULL)
	{
		RandomListNode* newnode = new RandomListNode(work->label);//新建结点
		mymap.insert({ work, newnode });//保存新旧结点:注意这个大括号对{}
		work = work->next;
	}
	//第二次遍历链表,根据旧结点的链接关系,给新结点赋予关系
	work = pHead;
	while (work != NULL)
	{
		RandomListNode* newnode = mymap.at(work);
		//if(work->next==NULL)
		   /// newnode->next=NULL;
		//else
		   // newnode->next=mymap.at(work->next);
		//根据旧结点,映射关系到新结点中去
		newnode->next = work->next ? mymap.at(work->next) : NULL;
		newnode->random = work->random ? mymap.at(work->random) : NULL;
		work = work->next;
	}
	return mymap.at(pHead);


#endif
	//方法二:多次遍历旧链表:需要3次
#if 1
		//1、根据旧链表创建新的结点
	RandomListNode* cur = pHead;
	RandomListNode* next;
	while (cur != NULL)
	{
		next = cur->next;//保留旧链表的下一个结点
		RandomListNode* newnode = new RandomListNode(cur->label);
		newnode->next = cur->next;
		cur->next = newnode;
		cur = next;//移到旧链表的下一个结点
	}
	//2、根据旧链表的结点关系给新结点赋予关系
	cur = pHead;
	while (cur != NULL)
	{
		RandomListNode* newnode = cur->next;
		if (cur->random == NULL)
		{
			newnode->random == NULL;
		}
		else
		{
			newnode->random = cur->random->next;//在旧结点的下一个结点
		}
		cur = newnode->next;//cur还是指向旧结点        
	}
	//3、拆分新旧链表
	cur = pHead;//旧链表
	RandomListNode* head = new RandomListNode(-1);//新链表头
	RandomListNode* p = head;
	p->next = NULL;
	while (cur != NULL)
	{
		if (cur->label == cur->next->label)//当前结点是旧结点
		{
			p->next = cur->next;
			cur->next = cur->next->next;//指向下一个旧的点

		}
		cur = cur->next;
		p = p->next;
		p->next = NULL;//保证结束的时候有链尾结点
	}
	return head->next;

#endif

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值