138. 复制带随机指针的链表
138. 复制带随机指针的链表
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的 深拷贝。
深拷贝指源对象和拷贝对象相互独立,其中任何一个对象的改动都不会对另一个对象造成影响。在进行赋值之前,为指针类型的数据成员另辟一个独立的内存空间,实现真正内容上的拷贝。
我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
思路:
1.从
head 节点开始遍历链表。首先创造新的 head 拷贝节点,并将该新建节点的引用也放入已访问字典中。2.random 指针
如果当前节点 i 的 random 指针指向一个节点 j 且节点 j 已经被拷贝过,我们将直接使用已访问字典中该节点的引用而不会新建节点。
如果当前节点 i 的 random 指针指向的节点 j 还没有被拷贝过,我们就对 j 节点创建对应的新节点,并把它放入已访问节点字典中。
3.next 指针
如果当前节点 i 的 next 指针指向的节点 j 在已访问字典中已有拷贝,我们直接使用它的拷贝节点。
如果当前节点 i 的next 指针指向的节点 j 还没有被访问过,我们创建一个对应节点的拷贝,并放入已访问字典。
如果当前节点 i 的next 指针指向的节点 j 还没有被访问过,我们创建一个对应节点的拷贝,并放入已访问字典。
4.我们重复步骤 2 和步骤 3 ,直到我们到达链表的结尾。
时间复杂度 o(n), 空间复杂度 o(n)。
代码:
/* // 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) { Node *old_node, *new_node, *head_new; if(!head) return head; unordered_map<Node*,Node*> m; old_node = head; new_node = new Node(old_node->val); m[old_node] = new_node; head_new = new_node; while(old_node) { if(old_node->random) new_node->random = copy(m, old_node->random); if(old_node->next) new_node->next = copy(m, old_node->next); old_node = old_node->next; new_node = new_node->next; } return head_new; } Node *copy(unordered_map<Node*, Node*> &m, Node *old_node1) { unordered_map<Node*, Node*>::iterator it = m.find(old_node1); Node *new_node1; if(it!=m.end()) { return it->second; } else { new_node1 = new Node(old_node1->val); m[old_node1] = new_node1; return new_node1; } } };
思路:
1.遍历原来的链表并拷贝每一个节点,将拷贝节点放在原来节点的旁边,创造出一个旧节点和新节点交错的链表。
2.迭代这个新旧节点交错的链表,并用旧节点的 random 指针去更新对应新节点的 random 指针。比方说, B 的 random 指针指向 A ,意味着 B' 的 random 指针指向 A' 。
3.现在
random 指针已经被赋值给正确的节点, 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==NULL) return head; Node *old_node, *new_node, *new_head; old_node = head; while(old_node) { new_node = new Node(old_node->val); new_node->next = old_node->next; old_node->next = new_node; old_node = new_node->next; } old_node = head; while(old_node) { new_node = old_node->next; if(old_node->random) new_node->random = old_node->random->next; old_node = old_node->next->next; } old_node = head; new_node = head->next; new_head = new_node; while(old_node) { old_node->next = old_node->next->next; if(new_node->next) new_node->next = new_node->next->next; old_node = old_node->next; new_node = new_node->next; } return new_head; } };
posted on 2020-07-29 21:33 Little-Prince 阅读(149) 评论(0) 收藏 举报
浙公网安备 33010602011771号