LeetCode138 链表的深度拷贝

题目

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
示例:
在这里插入图片描述

输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}
解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。

这个题目有一定难度的,难度在于随机指针。这个指针域该怎么复制是一个很重要的问题。
深度拷贝:原链表和新链表不互相影响,可以随意更改。
这个题目可以用map来计算,主要是存储随机指针之间的逻辑关系,map中存储的是地址和节点ID的映射。
难点有两点:
1.随机指针指向了哪一个节点?
2.这个节点的地址是多少?
而用map就是为了解决这两点的。

我自己的思路:首先存储随机指针指向的ID,然后新建新的指针,顺便保存值和指针以及随机指针三个参数,返回新的指针。

写代码发现行不通,不知道该怎么写,存储随机指针以及保存其他的指针都好写,但是怎么新建新指针和将新指针的next域、random域和原来的联系起来,这里不知道怎么写。

这里我的思路是有问题的,原因是我没有想清楚该做什么。我的思路是保存随机指针指向的ID,这一步保存ID是对的,但是随机指针不对,这里保存的应该是新链表中的指针,而不是旧链表,同理,新建新的指针时,值可以保存,但是next指针和随机指针不能一次性保存的。

正确的方法,应该是,根据原链表的长度建立新链表,仅仅将值域的值赋值,next域和random域暂时不用管,并且将新节点存放到vector中,然后保存旧节点的地址对应的id。

然后再次遍历旧节点,连接新节点的next域,然后由于map中保存的是旧节点的地址,所以对旧节点的random域取地址,该地址一定在map中,且对应的key值即为指向的id,结合该id在vector中索引,即可得到新节点中的random指针的地址。
最终代码如下:

Node* copyRandomList(Node* head)
{
	std::map<Node*, int > node_map;
	std::vector<Node*> node_vec;
	Node* ptr = head;
	int i = 0;
	while (ptr)
	{
		node_vec.push_back(new Node(ptr->val));
		//记录ptr 和ID的映射
		node_map[ptr] = i++;
		ptr = ptr->next;
	}

	node_vec.push_back(0);
	ptr = head;
	i = 0;
	while (ptr)
	{
		node_vec[i]->next = node_vec[i + 1];
		if (ptr->random!=NULL)
		{
			int id = node_map[ptr->random];//get ID
			node_vec[i]->random = node_vec[id];
		}
		ptr = ptr->next;
		i++;
	}
	return node_vec[0];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值