# LeetCode-剑指 Offer 35. 复杂链表的复制

123 阅读1分钟

题目

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

题解

这道题的意思就是通过new Node的方式,将原来的复杂链表从新链接一次。也就是说的复制。

这里唯一的变数就是random,不确定他会指向哪里。可能是指向后面的node。所以我们先遍历一边head,在遍历的同时在node上写上key其实就是下标,并保存在数组nodeArr上,因为对象都是引用,所以我们再次遍历数组时,就能通过下标找到random是数组中的哪个元素。即通过node.randomKey = node.random.key;同时我们创建新的node并保存在newArr中, 因为newArr与 nodeArr 位置是一一对应的,我们再一次遍历 newArr,且在nodeArr中找到对应的randomKey。当链表都绑好了,那么就返回newArr[0];

注意点:

当random === null时,我们将randomKey保存为-1,以便后面可以还原random=null

/**
 * // Definition for a Node.
 * function Node(val, next, random) {
 *    this.val = val;
 *    this.next = next;
 *    this.random = random;
 * };
 */
​
/**
 * @param {Node} head
 * @return {Node}
 */
var copyRandomList = function(head) {
    let nodeArr = [];
    let i = 0;
    let newArr = [];
    while(head!==null){
        head.key = i;
        nodeArr[i] = head;
        head = head.next;
        i++
    }
    
    nodeArr.forEach(node=>{
        if(node.random){
            node.randomKey = node.random.key;
        }else{
           node.randomKey = -1
        }
        newArr.push(new Node(node.val))
    })
​
    newArr.forEach((node,index)=>{
        if(nodeArr[index].randomKey === -1){
            node.random = null;
        }else{
            node.random = newArr[nodeArr[index].randomKey];
        }
        node.next = newArr[index+1] || null;
    })
    
    return newArr[0];
};