Medium
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
Example 1:
Input:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}
Explanation:
Node 1's value is 1, both of its next and random pointer points to Node 2.
Node 2's value is 2, its next pointer points to null and its random pointer points to itself.
Note:
- You must return the copy of the given head as a reference to the cloned list.
题目大意:给定一个链表,这个链表除了有一个next指针外,还有一个random指针随意指向任何地方。random会指向链表中的任意节点,包括自己,或指向NULL。对链表进行深度复制。
方法:
这道题和133 clone graph类似。使用hashmap记录节点和其复制节点的对应关系,和维系复制链表中的各节点间的链接。
方法一:迭代
使用队列迭代的依次对节点进行复制。如果map中没有next或者random指针对应的Node,就在map中插入对应的复制节点,如果已有对应节点则直接将next指针或random指针指向对应节点。
代码如下:
class Solution { public: Node* copyRandomList(Node* head) { if (!head)return NULL; Node* res = new Node(head->val, NULL, NULL); queue<Node*> q{ {head} }; map<Node*, Node*> m; m[head] = res; while (!q.empty()) { Node* t = q.front(); q.pop(); if (t) { if (t->next) { q.push(t->next); if (!m[t->next]) { m[t->next] = new Node(t->next->val, NULL, NULL); } } if (t->random && !m[t->random]) { m[t->random] = new Node(t->random->val, NULL, NULL); } m[t]->next = m[t->next]; m[t]->random = m[t->random]; } } return res; } };
方法二:递归
使用递归的方法进行复制。思路和迭代相似,只是用递归代替了队列对节点的读取。
代码如下:
class Solution { public: Node* copyRandomList(Node* head) { if (!head)return NULL; map<Node*, Node*> m; Node* res = copyNext(head, m); return res; } Node* copyNext(Node* head, map<Node*, Node*> &m) { if (!head)return NULL; Node* res = new Node(head->val, NULL, NULL); m[head] = res; if (head->next) { if (m[head->next]) { res->next = m[head->next]; } else res->next = copyNext(head->next, m); } if (head->random) { if (m[head->random]) { res->random = m[head->random]; } else res->random = copyNext(head->random, m); } return res; } };