[路飞]_leetcode_138.复制带随机指针的链表

110 阅读1分钟

思考

题目给出:

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。

解题思路

可以将每个节点复制一份,跟在节点的后面,然后复制的节点randdom应该指向它的指向节点的下一个节点。

1 -> 2 -> 3 -> 4 -> null;
|         ^
|_________|
 1.random

1 -> 1`-> 2 -> 2` -> 3 -> 3`-> 4 -> 4`->null
|                    ^
|____________________|
        1.random

1 -> 1`-> 2 -> 2` -> 3 -> 3`-> 4 -> 4`->null
     |                    ^
     |____________________|
          1.random.next

    |--------|
pre |       \/
1   1`  2 -> 2` -> 3 -> 3`-> 4 -> 4`->null
| pre.n  ^
|________|

代码

var copyRandomList = function(head) {
    let pre = head;
    // 复制节点到每个节点的后面
    while(pre) {
        pre.next = new Node(pre.val, pre.next, null);
        pre = pre.next.next;
    }
    // 7 7 13 13 11 11 10 10 0 0 null
    // 开始做random校正
    pre = head;
    while (pre) {
        pre.next.random = pre.random ? pre.random.next : null;
        pre = pre.next.next;
    }

    // 取出新的链表, 还要复原head
    pre = head;
    let newNode = cur = pre.next;
    while(pre) {
        pre.next = pre.next.next;
        cur.next = cur.next ? cur.next.next : null;
        pre = pre.next;
        cur = cur.next;
    }

    return newNode;
};