题目分析:
简单描述:
- 实现复杂链表的深度拷贝,即在复制链表的过程中额外构建新链表各节点的random引用指向
限制🚫
- -10000
- Node.random 为空(null)或指向链表中的节点。
- 节点数目不超过 1000 。
示例:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
解题思路:
思路:
- 在复制链表的过程中构建新链表各节点的 random 引用指向,可用以下两种方法:
- 1. #哈希表
- 使用unordered_map构建新节点 #[[C++ STL]]
- 2. 拼接+拆分
- 原地修改,在每个节点后添加一个相同值的节点
- 将新节点链接起来
- 分割成2条链表
效率:
- 时间复杂度
- 哈希表 空间复杂度
- 拼接+拆分 空间复杂度
- 哈希表 空间复杂度
代码:
- 1. #哈希表
class Solution
{
public:
/*使用基于哈希表的map*/
Node *copyRandomList(Node *head)
{
unordered_map<Node *, Node *> map;
if (head == NULL)
return head;
/*拷贝节点并放入map中*/
for (Node *i = head; i != NULL; i = i->next)
map.insert(make_pair(i, new Node(i->val)));
/*构建新节点的next和random的引用指向*/
for (Node *i = head; i != NULL; i = i->next)
{
if (i->next != NULL)
map.find(i)->second->next = map.find(i->next)->second; // next指向
if (map.find(i->random) != map.end())
map.find(i)->second->random = map.find(i->random)->second; // random指向
}
return map.find(head)->second;
}
};
- 2. 拼接+拆分
class Solution
{
public:
Node *copyRandomList(Node *head)
{
if (head == NULL)
return head;
/*原地修改,每个访问元素后复制一个同样元素,并完成next指向,形成1条链*/
for (Node *i = head; i != NULL; i = i->next->next)
{
Node *cpy = new Node(i->val);
cpy->next = i->next;
i->next = cpy;
}
/*构建新节点的random指向*/
for (Node *i = head; i != NULL; i = i->next->next)
{
/*1->1'->2->2'->3->3'...,此时要将1'的random指向1'2'3‘...链之一*/
if (i->random != NULL)
i->next->random = i->random->next;
}
/*将新旧节点分割成2条链*/
Node *nhead = head->next;
for (Node *i = head, *tmp = NULL; i != NULL && i->next != NULL;)
{
tmp = i->next;
i->next = tmp->next;
i = tmp;
}
return nhead;
}
};