[路飞]leetcode-138. 复制带随机指针的链表

85 阅读2分钟

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。这道题目描述很多,我就不粘过来凑字数了详情看力扣原文链接

示例 1:

image.png

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

解题思路1

1、遍历head,遍历过程中根据cur(当前节点),创建一个新的节点newNode, newNode.next指向cur.next,newNode.random指向cur.random,再将cur.next指向newNode,这样就形成了新旧节点混合在一起的,

2、再次遍历将新的newNode.random指向newNode.random.next,因为所有的新节点random都指向对应对象老节点的random,而每个节点后都跟了对应的新节点,所以newNode.random.next会指向对应心创建的节点

var copyRandomList = function (head) {
  if (!head) {
    return head;
  }
  let cur = head;
  while (cur) {
    nodeItem = new Node(cur.val);
    nodeItem.random = cur.random;
    // next=cur.next
    nodeItem.next = cur.next;
    // nodeItem.target="new"
    cur.next = nodeItem;
    cur = nodeItem.next;
  }
  cur = head.next;
  while (cur) {
    if (cur.random) {
      cur.random = cur.random.next;
    }
    cur = cur.next?.next;
  }
  newList = head.next;
  cur = head;
  while (cur) {
    newCur = cur.next;
    cur.next = newCur.next;
    if (cur.next) {
      newCur.next = cur.next.next;
    }
    cur = cur.next;
  }
  return newList;
};

第二种方法

第一种方法是拾人牙慧,这第二种是自己思考出来的,虽然代码比较少但每次的成绩都不如第一种,但这也是自己的成果和一种突破吧,下面是解题思路和代码

创建两个数组oldList、newList,分别存储新旧节点

第一次遍历,创建新节点并存储,存储旧节点

第二次遍历,根据key找到老节点,并判断是否有random,有就在newList中找到对应的randomkey,根据randomKey将cur.random=oldList[randomKey]

var copyRandomList = function (head) {
    if(!head)return head
    let newList=[];
    let oldList=[];
    let cur=head
    while(cur){
        newList.push(new Node(cur.val))
        oldList.push(cur)
        cur=cur.next
    }
    oldList.forEach((item,key) => {
        if(newList[key+1]){
            newList[key].next=newList[key+1]
        }
        if(oldList[key].random){
            let randomKey=oldList.findIndex(v=>v==oldList[key].random)
            newList[key].random=newList[randomKey]
        }
    });
    return newList[0]
}