[路飞]_深夜复制带随机指针的链表

489 阅读2分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

1721. 交换链表中的节点

哈希表

借用哈希表存储新数据

假设现在有一个链表如下图所示

image.png

1、根据原链表创建新链表节点;7、13、11、10、1;这一步没问题吧?
2、暂时不需要知道新链表节点的关系,只需要将新建节点放在Map中;这一步理解起来没问题吧?
3、新节点放在Map中,存放规则是:key为老链表的当前节点,value为以链表当前节点value创建出来的新节点;这一步理解起来也不难吧?
4、再次遍历原链表,将Map中的节点取出,链接对应关系;

比如:
当前节点是7;从Map中找到key为7的value;

将节点7的下一指针节点作为Map的key找到value2;

那么value.next = value2;即可将新链表中当前节点关系关联起来;

同理:

将节点7的random指针作为Map的key找到value3;
则有value.random = value3;

根据上述思路编辑代码如下:

var copyRandomList = function(head) {
    let header = head
    const map = new Map();
    while(header){
        map.set(header,new Node(header.val))
        header = header.next
    }
    header = head;

    while(header){
        const current = map.get(header)
        current.next = map.get(header.next)||null;
        current.random = map.get(header.random)||null;
        header = header.next
       
    }
    return map.get(head)
    
};

时间复杂度O(n)
空间复杂度O(n)

原链表修改法

该方法是在原链表上修改得到新链表

怎么个思路呢?

image.png

如上图;

在遍历原链表过程中,生成新链表;

比如原链表为

graph LR
7 --> 13--> 11--> null

生成新链表为

graph LR
7 --> 7'--> 11-->11' --> 13--> 13'--> null

假设原链表有

graph LR
7 --> 13--> 7-->11 --> null

节点7下一节点指向13,随机节点指向11;

那么节点7'在节点7的下一位置;是不是可以根据7得到7' 那么节点7下一节点指向13,13的下一节点是13‘是不是可以将7'和13'的关系对应起来?

将关系一一对应后,将新链表从原链表分离出来即可:

根据上述思路编辑代码如下:


var copyRandomList = function(head) {
    if(head === null) return;
    let current  = head;

    //生成新的链表
    while(current){
        const next = current.next;
        current.next = new Node(current.val)
        current.next.next = next;
        current = next
    }

    // 重新设置指针
    current = head;
    while(current){
        const next = current.next.next;
        const newCurr = current.next;
        newCurr.random = current.random!==null?current.random.next:null;
        current = next
    }

    let result = head.next;
     current = head;
     while(current){
          const next = current.next.next;
          const newCurr = current.next;
          current.next = next;
          newCurr.next = next!==null?next.next:null;
          current = next
     }
     return result
    
};

过程比较复杂:学完比较有成就