Problem:
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.
The Linked List is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index]
where:
val
: an integer representingNode.val
random_index
: the index of the node (range from0
ton-1
) where random pointer points to, ornull
if it does not point to any node.
Example 1:
Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
Example 2:
Input: head = [[1,1],[2,1]]
Output: [[1,1],[2,1]]
Example 3:
Input: head = [[3,null],[3,0],[3,null]]
Output: [[3,null],[3,0],[3,null]]
Example 4:
Input: head = []
Output: []
Explanation: Given linked list is empty (null pointer), so return null.
Constraints:
-10000 <= Node.val <= 10000
Node.random
is null or pointing to a node in the linked list.Number of Nodes will not exceed 1000.
思路1:
Solution:
Node* copyRandomList(Node* head) {
Node *newHead, *l1, *l2;
if (head == NULL) return NULL;
for (l1 = head; l1 != NULL; l1 = l1->next->next) {
l2 = new Node(l1->val);
l2->next = l1->next;
l1 -> next = l2;
}
newHead = head->next;
for (l1 = head; l1 != NULL; l1 = l1->next->next) {
if (l1->random != NULL) l1->next->random = l1->random->next;
}
for (l1 = head; l1 != NULL; l1 = l1->next) {
l2 = l1->next;
l1->next = l2->next;
if (l2->next != NULL) l2->next = l2->next->next;
}
return newHead;
}
性能:
Runtime: 16 ms Memory Usage: 11.1 MB
思路2:
建立一个哈希表unordered_map<Node*, Node*>
,key值为指向原链表结点的指针,value为指向复制链表结点的指针,首先遍历原链表,复制出新的链表并用next
指针连接。然后遍历原链表,用random
指针连接。
Solution (C++):
Node* copyRandomList(Node* head) {
if (!head) return NULL;
using N = Node*;
unordered_map<N, N> hash;
N old_head = head;
N new_head = new Node(head->val);
hash[old_head] = new_head;
while (old_head->next) {
new_head->next = new Node(old_head->next->val);
old_head = old_head->next;
new_head = new_head->next;
hash[old_head] = new_head;
}
old_head = head;
new_head = hash[old_head];
while (old_head && new_head) {
new_head->random = old_head->random ? hash[old_head->random] : NULL;
old_head = old_head->next;
new_head = new_head->next;
}
return hash[head];
}
性能:
Runtime: 12 ms Memory Usage: 11.1 MB
思路3:
思路2的简化版本。
Solution (C++):
Node* copyRandomList(Node* head) {
if (!head) return NULL;
Node *newHead, *l1 = head, *l2;
for (l1; l1; l1 = l1->next->next) {
l2 = new Node(l1->val);
l2->next = l1->next;
l1 -> next = l2;
}
newHead = head->next;
for (l1 = head; l1; l1 = l1->next->next) {
if (l1->random) l1->next->random = l1->random->next;
}
for (l1 = head; l1; l1 = l1->next) {
l2 = l1->next;
l1->next = l2->next;
if (l2->next) l2->next = l2->next->next;
}
return newHead;
}
性能:
Runtime: 12 ms Memory Usage: 11.1 MB