复制带随机指针的链表
复制一个带随机指针的链表,并返回新链表
解题代码
解题思路:
- 两两复制,把每个节点到当前节点的下一位,如1->2->3 = 1->1->2->2->3->3
- 这时每个节点的random都指向的是同一个节点,但是复制的节点应该指向被复制节点的下一位
- 如1->random = 2, 1'->random = 2'(被复制节点的下一位)
- 然后将链表拆成两个独立的链表,就完成链表的复制。
var copyRandomList = function(head) {
if (!head) return null;
let p = head;
let q;
while (p) { // 两两复制
q = new Node(p.val); // 复制当前节点
q.random = p.random; // 连接相同的随机指针域
q.next = p.next; // 把p的下个节点指向我们复制出来的节点
p.next = q; // 把当前节点的下个节点指向到复制节点 此时完成如1->1的复制
p = q.next // p往后走一步 继续循环直至链表结束(因为原链表的p.next被插入复制节点后,此时的正确位置是q.next)
}
p = head.next; // 重新赋值为链表头节点
while (p) { // 修正随机指针域
if (p.random) p.random = p.random.next; // 复制节点的random,应该是在被复制的下一位。
p = (p.next?.next || p.next ); // 走两步,因为有相同的复制节点。 如果next.next不存在那么就直接赋予next
}
let newHead = head.next; // 新链表的第一个节点
p = head; // 原链表的第一个节点
while (p) { // 拆分链表
q = p.next; // 第一次进入时,q设置为新链表的第一个节点,也就是复制节点。
p.next = q.next; // 原链表指向复制节点的下一位。如 1 -> 1` -> 2 -> 2` = 1(p) -> 2(q.next)
if (p.next) q.next = p.next.next; // 新链表指向原链表的下一位的下一位。如 1 -> 1` -> 2 -> 2` = 1`(q) -> 2`(p.next.next)
p = p.next; // p往后走一步,继续循环,直至链表为空即可。
}
return newHead; // 返回复制链表
};