【剑指offer】复杂链表的复制

剑指offer面试题26:复杂链表的复制

题目 :



复杂链表的结点的定义如下:

//链表的结点的定义为:
struct ComplexListNode
{
	int	val ;						//结点内保存的值
	ComplexListNode* my_pNext;		//节点的next指针
	ComplexListNode* my_pSibling;	//表示的是随机指针
	ComplexListNode(const  int  value)
		:val(value)
		,my_pSibling(NULL)
		,my_pNext(NULL)
	{}
};


复杂链表的结构实体图:



对于这样的题目 ,很多的人的第一思路 就是分成的两步:
1、先复制链表的结点,并使用next指针链接起来;
2、在 设置每一个结点的随机指针。

但是这种方法,在设置结点随机指针的 过程中 ,要先遍历一遍 链表找随机指针在链表的指向的位置 ,
那么,每一个结点都这么找一下话,那么这个函数的时间复杂度 ,就是O(N );
要是面试的时候,你被问到的是这个题目,你这要回答,那么面试官肯定不会满意的。。
一句话,再好好想想吧!!!

在这里就交给你一种简单的方法,来解决这种复杂问题的复制:
1、将新复制的每一个结点的连接到源结点的后面 ,(先不管随机指针);


2、设置复制后的结点的随机指针;

但是要怎么来设置呢???(经典的地方)
  如果仔细看的话  ,,我们就会发现,随机指针的指向,就是原结点的随机指针的next结点(NULL除外 )


3、指针设置好后,那么就要断开连接,得到复制后的链表的头结点

实现的结果:


代码实现:
//面试题26 :复杂李彪链表的复制 
//链表的结点的定义为:
struct ComplexListNode
{
	int	val ;						//结点内保存的值
	ComplexListNode* my_pNext;		//节点的next指针
	ComplexListNode* my_pSibling;	//表示的是随机指针
	ComplexListNode(const  int  value)
		:val(value)
		,my_pSibling(NULL)
		,my_pNext(NULL)
	{}
};


//要实现这个问题的话 ,要是么有什么限制的话,那是很简单的;
//但是这个样子是很难闹到offer的;
ComplexListNode*  CopyComplexList(ComplexListNode* head)
{
	ComplexListNode* ret = NULL;//使用的是 ret表示的是  要返回的复制后的链表后的结点
	if(head == NULL)
		return  ret;//表示的是 当原有的链表为 空的话 ,那么直接返回的kong;
	//先建立新的结点连接到 当前的结点后面 ,,,方便   随机指针的链接 

	//  1、 第一步代码  ************
	ComplexListNode*  cur  = head;
	while(cur)
	{
		ComplexListNode * node =  new ComplexListNode(cur->val);//先用当前的结点的值 复制一个结点连接到当前节点的后面 
		//链接
		node->my_pNext = cur->my_pNext;
		cur->my_pNext = node;

		cur = node->my_pNext;
	}
	//  2、 第二步代码  ************
	//链接完成后 就到了链接  随机指针
	cur = head;
	while(cur)
	{
		//node表示的是新生成的结点
		ComplexListNode*  node = cur->my_pNext;
		//链接随机指针
		if(cur->my_pSibling)//这个判断很重要的
			node->my_pSibling = cur->my_pNext->my_pNext;
		cur  = node->my_pNext;
	}
	//  3、 第三步代码  ************
	//断开连接
	cur  = head;
	ComplexListNode* prev = NULL;
	while(cur)
	{
		//node表示的是新生成的结点
		ComplexListNode*  node = cur->my_pNext;
		cur ->my_pNext =  node->my_pNext;
		cur = cur->my_pNext;

		if(prev)
		{
			prev->my_pNext = node;
			ret  = node;
		}
		prev  = node;
	}
	return  ret;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值