给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。这道题目描述很多,我就不粘过来凑字数了详情看力扣原文链接
示例 1:
输入: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]
}