请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
示例 4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
提示:
-10000 <= Node.val <= 10000
Node.random 为空(null)或指向链表中的节点。
节点数目不超过 1000 。
解题思路
- 在每个节点后面复制一个与它完全值和下一节点相同的节点
- 每一个真实节点的random指针可以通过位置指定
- 例如:A−>B−>CA->B->CA−>B−>C
- 如果AAA的randomrandomrandom指针指向CCC,那么经过第一个步骤后,链表就会变成:A−>A′−>B−>B′−>C−>C′A->A'->B->B'->C->C'A−>A′−>B−>B′−>C−>C′
- 此时random(A)−>Crandom(A)->Crandom(A)−>C,只需要让A′A'A′指向random(A)−>next−>nextrandom(A)->next->nextrandom(A)−>next−>next即可
- 例如:A−>B−>CA->B->CA−>B−>C
- 最后拆分链表就能得到一个复制后的链表
代码展示
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
void CloneNodes(Node* head)
{
Node* pNode=head;
while(pNode!=nullptr)
{
Node* pClone = new Node(pNode->val);
pClone->next = pNode->next;
pClone->random= pNode->random;
pNode->next = pClone;
pNode = pClone->next;
}
}
void ConnectSiblingNodes(Node* head)
{
Node* pNode = head;
while(pNode != nullptr)
{
Node* pClone = pNode->next;
if(pNode->random !=nullptr)
{
pClone->random = pNode->random->next;
}
pNode = pClone->next;
}
}
Node* ReconnectNodes(Node* head)
{
Node* pNode = head;
Node* pCloneHead = nullptr;
Node* pCloneNode = nullptr;
if(pNode != nullptr)
{
pCloneHead = pCloneNode = pNode->next;
pNode->next = pCloneNode->next;
pNode = pNode->next;
}
while(pNode !=nullptr)
{
pCloneNode->next = pNode->next;
pCloneNode = pCloneNode->next;
pNode->next = pCloneNode->next;
pNode = pNode->next;
}
return pCloneHead;
}
Node* copyRandomList(Node* head) {
CloneNodes(head);
ConnectSiblingNodes(head);
return ReconnectNodes(head);
}
};
本文介绍了一种高效复制复杂链表的方法,该链表包含next和random指针。通过在每个节点后插入副本,调整random指针,并最终分离原始链表和副本链表,实现了复杂链表的完整复制。
936

被折叠的 条评论
为什么被折叠?



