题目描述:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
输入: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]]
解题思路:
自己的思路:依次循环链表并创建新的节点,由于任意节点可能当前没有创建,所以先跳过任意节点,只复制值和next节点。
当创建好新链表后,对两个链表同时循环,由于两个链表的任意节点位置是相同的,故当循环到初始链表某节点的任意节点时,此时新链表循环到的地方也是某节点的任意节点。
代码:
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==NULL)
{
return head;
}
Node* newHead = new Node(head->val);
newHead->next = NULL;
newHead->random=NULL;
Node* pre = newHead;
Node* cur = head->next;
while(cur)
{
Node* newNode=new Node(cur->val);
pre->next=newNode;
pre = newNode;
cur = cur->next;
}
Node* cur2 = head;
Node* copyCur2 = newHead;
while(cur2)
{
Node* point = head;
Node* copyPoint = newHead;
while(point)
{
if(point==cur2->random)
{
break;
}
point = point->next;
copyPoint = copyPoint->next;
}
copyCur2->random = copyPoint;
cur2 = cur2->next;
copyCur2 = copyCur2->next;
}
return newHead;
}
};
官方思路:不新建链表,而是在原链表中插入节点,如下图。
插入节点后找每个节点的任意节点,每个新插入的节点的任意节点都为前一个节点的任意节点的下一个。最后再将拼接后的链表拆成两个链表。
代码:
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==nullptr)
{
return nullptr;
}
Node* cur = head;
while(cur)
{
Node* newNode = new Node(cur->val);
newNode->next = cur->next;
cur->next = newNode;
cur = newNode->next;
}
Node* cur2 = head;
while(cur2)
{
Node* ranNode = cur2->random;
if(ranNode==nullptr)
{
cur2->next->random=nullptr;
}
else
{
cur2->next->random = ranNode->next;
}
cur2 = cur2->next->next;
}
Node* newHead = head->next;
Node* node = head;
while(node)
{
Node* n = node->next;
node->next = node->next->next;
node = node->next;
if(n->next!=nullptr)
{
n->next = n->next->next;
}
}
return newHead;
}
};