哈希表映射旧节点到新节点,第二遍补 next/random 引用。
OJ: leetcodecn
题目 ID: copy-list-with-random-pointer
难度:普及+/提高
标签:链表哈希表cpppython
日期: 2026-07-28 22:05
题意
复制带随机指针的链表,返回深拷贝。random 指针可指向任意节点或 null。
思路
哈希表第一遍遍历创建所有新节点并建立映射,第二遍遍历补全 next 和 random。O(n) 时间 O(n) 空间。
进阶:节点交错插入法(旧->新->旧->新…)可做到 O(1) 额外空间。
代码
cpp
/**
* Author by Rainboy
*/
// main.cpp:哈希表映射,两遍遍历。
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int val;
Node *next;
Node *random;
Node(int _val) : val(_val), next(nullptr), random(nullptr) {}
};
class Solution {
public:
Node *copyRandomList(Node *head) {
if (!head)
return nullptr;
unordered_map<Node *, Node *> m;
for (auto p = head; p; p = p->next)
m[p] = new Node(p->val);
for (auto p = head; p; p = p->next) {
m[p]->next = m[p->next];
m[p]->random = m[p->random];
}
return m[head];
}
};
Node *build(istream &in, int n) {
if (!n)
return nullptr;
vector<Node *> nodes(n);
for (int i = 0, v; i < n; i++) {
in >> v;
nodes[i] = new Node(v);
}
for (int i = 0; i < n - 1; i++)
nodes[i]->next = nodes[i + 1];
return nodes[0];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
auto head = build(cin, n);
auto copied = Solution().copyRandomList(head);
for (auto p = copied; p; p = p->next)
cout << p->val << ' ';
return 0;
}python
#!/usr/bin/env python3
class Node:
def __init__(self, x):
self.val = x
self.next = None
self.random = None
class Solution:
def copyRandomList(self, head: Node) -> Node:
if not head:
return None
m = {}
p = head
while p:
m[p] = Node(p.val)
p = p.next
p = head
while p:
m[p].next = m.get(p.next)
m[p].random = m.get(p.random)
p = p.next
return m[head]
def build(arr):
if not arr:
return None
nodes = [Node(v) for v in arr]
for i in range(len(nodes) - 1):
nodes[i].next = nodes[i + 1]
return nodes[0]
def main() -> None:
n = int(input())
a = list(map(int, input().split()))
head = build(a)
copied = Solution().copyRandomList(head)
while copied:
print(copied.val, end=" ")
copied = copied.next
if __name__ == "__main__":
main()复杂度
- 时间复杂度:O(n)。
- 空间复杂度:O(n)。
总结
拷贝指针问题中哈希表是最直观的解法。交错插入法优化了空间,但增加了实现复杂度。