给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。
构造这个链表的
深拷贝
。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
解法 暴力解法map+两次遍历
思路
深复制需要复制原链表的 random
关系,而在遍历过程中,可能 random
上的新节点还没有被创建出来,无法实现,所以需要两次遍历。
可以第一次遍历先创建节点,并且使用 map
来保存新链表和老链表之间各个节点的对应关系,在第二次遍历中再去关联新链表的 random
指针。
代码
function copyRandomList(head: _Node | null): _Node | null {
const map = new Map<_Node, _Node>();
let dummyHead = new _Node(-1);
let cur = dummyHead;
let current = head;
while (current) {
const node = new _Node(current.val);
map.set(current, node);
cur.next = node;
cur = cur.next;
current = current.next;
}
current = head;
cur = dummyHead.next;
while (current) {
cur.random = map.get(current.random) ?? null;
cur = cur.next;
current = current.next;
}
return dummyHead.next;
};
时空复杂度
时间复杂度:没有嵌套遍历 O(n)
空间复杂度:缓存了所有链表节点所以是 O(n)