LeetCode 138. 复制带随机指针的链表
1 题目描述
- 题目链接:138. 复制带随机指针的链表
给你一个长度为 n
的链表,每个节点包含一个额外增加的随机指针 random
,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。 深拷贝应该正好由 n
个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next
指针和 random
指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
例如,如果原链表中有 X
和 Y
两个节点,其中 X.random --> Y
。那么在复制链表中对应的两个节点 x
和 y
,同样有 x.random --> y
。
返回复制链表的头节点。
用一个由 n
个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index]
表示:
val
:一个表示Node.val
的整数。random_index
:随机指针指向的节点索引(范围从0
到n-1
);如果不指向任何节点,则为null
。
你的代码 只 接受原链表的头节点 head
作为传入参数。
示例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]]
2 思路
- 迭代+链表拆分
- 遍历原链表,复制每一个节点,并将新节点连在原节点之后,即
node->next = new_node
. - 重新遍历链表,并根据原链表的
random
指向修改复制节点的random
指针。具体的实现方法是:node->next->random = node->random->next
.这里node
指原链表的节点,node->next
为复制节点,node->random
指向原链表的节点的random
节点,而对应的,node->random->next
则为复制节点node->next
的random
节点。 - 遍历整个链表,将当前遍历的节点的
next
节点存储下来,然后将当前节点的next
指向下下个节点,从而实现两个链表的拆分。
- 遍历原链表,复制每一个节点,并将新节点连在原节点之后,即
/*
// 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) return head;
Node *cur = head;
while(cur){
Node *node = new Node(cur->val);//将所复制的节点连在原链表对应节点的后边
node->next = cur->next;
cur->next = node;
cur = cur->next->next;
}
cur = head;
while(cur){ //按照原链表的random指针修改复制链表的random指向
if(cur->random){
cur->next->random = cur->random->next;
}else{
cur->next->random = nullptr;
}
cur = cur->next->next;
}
Node *newHead = head->next;
cur = head;
while(cur && cur->next){
Node *next = cur->next; //拆分链表并还原两个链表
cur->next = next->next;
cur = next;
}
return newHead;
}
};
- 回溯+哈希
- 创建一个
Key
为Node
节点,val
为Node
节点的map
. - 遍历链表,复制当前节点并将当前节点作为
key
, 而新节点作为val
插入map
中. - 复制完链表后,遍历链表,按照
map
中的关系,将复制原链表的random
指向。
- 创建一个
class Solution {
public:
map<Node*, Node*> m;
Node* copyRandomList(Node* head) {
if(!head) return nullptr;
if(m.count(head)){
return m[head];
}
Node *addNode = new Node(head->val);
m[head] = addNode;
addNode->next = copyRandomList(head->next);
addNode->random = copyRandomList(head->random);
return addNode;
}