剑指offer JS题解 (25)复杂链表的复制

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

解题思路

这道题有三种解法。
第一种是先拷贝节点,用next连接起来。之后从头开始遍历节点,对每个节点根据random值去寻找节点,再做连接。时间复杂度为O(n²)。
第二种是使用哈希表,通过哈希表来对应拷贝前后的两个复杂链表,这样一来,就可以通过原链表的random作为键,取到新链表的random应该指向的结点。
第三种是对链表进行拓展,第一次遍历时在每个结点之后创建拷贝结点,第二次遍历时根据兄弟结点,连接上random结点,第三次遍历时则将两倍长度的链表拆开,取得复制链表。时间复杂度为O(n)。见下图:
解法三,扩展链表

Code

// 解法二 哈希表

/*function RandomListNode(x){
    this.label = x;
    this.next = null;
    this.random = null;
}*/
function Clone(pHead)
{
    // write code here
    if(!pHead) return null;
    const map=new Map();
    let p,p2;
    p=pHead;
    p2=new RandomListNode(pHead.label);
    const pHead2=p2;
    map.set(p,p2);
    while(p){
        if(p.next) p2.next=new RandomListNode(p.next.label);
        else p2.next=null;
        p=p.next;
        p2=p2.next;
        map.set(p,p2);
    }
    p=pHead;
    p2=pHead2;
    while(p){
        p2.random=map.get(p.random);
        p=p.next;
        p2=p2.next;
    }
    return pHead2;
}

// 解法三 拓展链表

/*function RandomListNode(x){
    this.label = x;
    this.next = null;
    this.random = null;
}*/
function Clone(pHead)
{
    // write code here
      cloneNodes(pHead);
      connectRandom(pHead);
      return reconnectNodes(pHead);
}
function cloneNodes(pHead) {
  // 复制链表
  let pNode = pHead;
  while (pNode) {
    const newNode = new RandomListNode(pNode.label);
    newNode.next = pNode.next;
    pNode.next = newNode;
    pNode = newNode.next;
  }
}
function connectRandom(pHead) {
  // 设置random指针
  let pNode = pHead;
  while (pNode) {
    if (pNode.random) {
      pNode.next.random = pNode.random.next;
    }
    pNode = pNode.next.next;
  }
}
function reconnectNodes(pHead) {
  // 拆开链表
  let pNode = pHead;
  let newNodeHead = null,
    newNode = null;
  if (pNode) {
    newNodeHead = newNode = pNode.next;
    pNode.next = newNode.next;
    pNode = newNode.next;
  }
  while (pNode) {
    newNode.next = pNode.next;
    newNode = newNode.next;
    pNode.next = newNode.next;
    pNode = pNode.next;
  }
  return newNodeHead;
}

运行环境:JavaScript (V8 6.0.0)
运行时间:17ms
占用内存:5432k

猜你喜欢

转载自blog.csdn.net/qq_40340478/article/details/106183500