Solution 1
核心问题:random指针乱指,如果像next一样构造节点,可能出现random指向未创建的情况。
解决思路:两次遍历,第一遍按照原有的next创建所有节点,然后仿照既有节点的random创建新的random链接
需要注意:怎么找到新的节点,哈希表或者直接传在原有链表中(相当于ab之间串入新的a)
优劣分析:前者需要占用额外空间但只需要遍历两次,后者实现稍微复杂,需要遍历三次,但是不需要占用额外空间
实现第一个方案,用哈希表(不过为啥实际还慢了??可能需要进一步调优)
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n为输入链表的长度,遍历二次
- 空间复杂度: O ( n ) O(n) O(n),其中 n n 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) {
unordered_map<Node*, Node*> mapNode;
if (head == nullptr) {
return nullptr;
}
Node* prevNew = nullptr;
Node* headNew = nullptr;
for (auto node = head; node != nullptr; node = node->next) {
auto nodeNew = new Node(node->val);
if (prevNew == nullptr) {
prevNew = nodeNew;
headNew = nodeNew;
} else {
prevNew->next = nodeNew;
prevNew = nodeNew;
}
mapNode[node] = nodeNew;
}
for (auto node = head; node != nullptr; node = node->next) {
mapNode[node]->random = mapNode[node->random];
}
return headNew;
}
};
Solution 2
实现第二个方案()
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n为输入链表的长度,遍历三次
- 空间复杂度: O ( 1 ) O(1) O(1),仅维护常数个状态量
/*
// 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 == nullptr) {
return nullptr;
}
for (auto node = head; node != nullptr; node = node->next->next) {
// 创建副本节点
auto nodeNew = new Node(node->val);
nodeNew->next = node->next;
node->next = nodeNew;
}
for (auto node = head; node != nullptr; node = node->next->next) {
// 复制random链接
auto nodeNew = node->next;
if (node->random != nullptr) {
nodeNew->random = node->random->next;
}
}
auto headNew = head->next;
for (auto node = head; node != nullptr; node = node->next) {
// 剥离链表
auto nodeNew = node->next;
node->next = node->next->next;
if (nodeNew->next != nullptr) {
nodeNew->next = nodeNew->next->next;
}
}
return headNew;
}
};
Solution 3
Solution 1的Python实现
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
if head is None: return None
mapNode = dict()
prevNew, headNew = None, None
node = head
while node is not None:
nodeNew = Node(node.val)
if prevNew is None:
prevNew = nodeNew
headNew = nodeNew
else:
prevNew.next = nodeNew
prevNew = nodeNew
mapNode[node] = nodeNew
node = node.next
node = head
while node is not None:
mapNode[node].random = mapNode[node.random] if node.random is not None else None
node = node.next
return headNew
Solution 4
Solution 2的Python实现
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
if head is None: return None
node = head
while node is not None:
nodeNew = Node(node.val)
nodeNew.next = node.next
node.next = nodeNew
node = node.next.next
node = head
while node is not None:
nodeNew = node.next
nodeNew.random = node.random.next if node.random is not None else None
node = node.next.next
headNew = head.next
node = head
while node is not None:
nodeNew = node.next
node.next = node.next.next
nodeNew.next = nodeNew.next.next if nodeNew.next is not None else None
node = node.next
return headNew