鏈表節點含 next 和 random 指針。深拷貝返回新鏈表頭。
map[old] = newnew.next = map[old.next],new.random = map[old.random]
Node copyRandomList(Node head) {
if (!head) return null;
Map map = new HashMap<>();
for (Node p=head; p!=null; p=p.next) map.put(p, new Node(p.val));
for (Node p=head; p!=null; p=p.next) {
Node q = map.get(p);
q.next = map.get(p.next);
q.random = map.get(p.random);
}
return map.get(head);
}
A → A' → B → B' → ...random:A'.random = A.random ? A.random.next : null
Node copyRandomList(Node head) {
if (!head) return null;
// 1. 複製節點插入原鏈表
for (Node p=head; p!=null; p=p.next.next) {
Node copy = new Node(p.val);
copy.next = p.next;
p.next = copy;
}
// 2. 設置 random
for (Node p=head; p!=null; p=p.next.next)
if (p.random != null) p.next.random = p.random.next;
// 3. 拆分
Node newHead = head.next;
for (Node p=head; p!=null; p=p.next) {
Node copy = p.next;
p.next = copy.next;
copy.next = (copy.next != null) ? copy.next.next : null;
}
return newHead;
}
| 方法 | 時間 | 額外空間 |
|---|---|---|
| 哈希表 | O(n) | O(n) |
| 原地拆分 | O(n) | O(1) |