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.
涉及到deep copy,采用Hashmap最简单,此题还有一种巧妙地解法,有时要求让用O(1)复杂度,就需要此巧妙解法。
方法一: HashMap
C++中Hashmap数据结构是:unordered_map< type1, type2>
- 先把各点copy出来,记录到HashMap中
- 再次遍历各点,构造next和random指针。
/**
* Definition for singly-linked list with a random pointer.
* struct RandomListNode {
* int label;
* RandomListNode *next, *random;
* RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:
/**
* @param head: The head of linked list with a random pointer.
* @return: A new head of a deep copy of the list.
*/
RandomListNode *copyRandomList(RandomListNode *head) {
if (head == NULL) {
return NULL;
}
unordered_map<RandomListNode*, RandomListNode*> old2new;
RandomListNode *crt = head;
while(crt != NULL) {
RandomListNode * new_node = new RandomListNode(crt->label);
old2new[crt] = new_node;
crt = crt->next;
}
crt = head;
while (crt != NULL) {
old2new[crt]->next = old2new[crt->next];
old2new[crt]->random = old2new[crt->random];
crt = crt->next;
}
return old2new[head];
}
};
方法二:巧妙解法
1->2->3
- 复制的节点接到节点next:
a. ->next接新建的mapping的节点
b. ->next->next接以前的next节点
1->1'->2->2'->3->3'
- 复制random(注意
crt->random
可能为NULL,此时不复制) - 最后split开,(把偶数和奇数拆开)
/**
* Definition for singly-linked list with a random pointer.
* struct RandomListNode {
* int label;
* RandomListNode *next, *random;
* RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:
/**
* @param head: The head of linked list with a random pointer.
* @return: A new head of a deep copy of the list.
*/
RandomListNode *copyRandomList(RandomListNode *head) {
if (head == NULL) {
return NULL;
}
RandomListNode *crt = head;
while (crt != NULL) {
RandomListNode * new_node = new RandomListNode(crt->label);
new_node->next = crt->next;
crt->next = new_node;
crt = crt->next->next;
}
crt = head;
while (crt != NULL && crt->next != NULL) {
if (crt->random != NULL) {
crt->next->random = crt->random->next;
}
crt = crt->next->next;
}
crt = head->next;
while (crt != NULL && crt->next != NULL) {
crt->next = crt->next->next;
crt = crt->next;
}
return head->next;
}
};