⭐️坚持每天一道力扣题
复杂链表的复制
方法:拼接 + 拆分
考虑构建 原节点 1 -> 新节点 1 -> 原节点 2 -> 新节点 2 -> ……
的拼接链表,如此便可在访问原节点的random
指向节点的同时找到新对应新节点的 random
指向节点。
算法流程:
- 复制各节点,构建拼接链表:
-
设原链表为 node1→node2→⋯ ,构建的拼接链表如下所示:
n o d e 1 → n o d e 1 n e w → n o d e 2 → n o d e 2 n e w → ⋯ node1→node1~new~ →node2→node2~new~ →⋯ node1→node1 new →node2→node2 new →⋯
- 构建新链表各节点的 random 指向:
- 当访问原节点
cur
的随机指向节点cur.random
时,对应新节点cur.next
的随机指向节点为cur.random.next
。
- 拆分原 / 新链表:
- 设置
pre
/cur
分别指向原 / 新链表头节点,遍历执行pre.next = pre.next.next
和cur.next
=cur.next.next
将两链表拆分开。
返回新链表的头节点ret
即可。
/*
// 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:
Node* copyRandomList(Node* head) {
if(head == NULL)
{
return NULL;
}
Node* cur = head;
while(cur)
{
//1、创建新节点插入在原节点后面
Node* copy = (Node*)malloc(sizeof(Node));
copy->val = cur->val;
//插入copy节点
copy->next = cur->next;
cur->next = copy;
cur = copy->next;
}
//2、根据原节点,处理原节点的radom
cur = head;
while(cur)
{
Node* copy = cur->next;
if(cur->random == NULL)
copy->random = NULL;
else
copy->random = cur->random->next;
cur = copy->next;
}
Node* copyHead = NULL, *copyTail = NULL;
cur = head;
while(cur)
{
Node* copy = cur->next;
Node* next = copy->next;
if(copyTail == NULL)
{
copyHead = copyTail = copy;
}
else
{
copyTail->next = copy;
copyTail = copy;
}
//恢复原链表
cur->next = next;
cur = next;
}
return copyHead;
}
};