【力扣刷题笔记】复杂链表的复制 JavaScript实现
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
下面是我的错误代码示范(虽然能跑过力扣的所有测试用例,而且耗时很短,但是在数据大量重复时无法使用)
/**
* // Definition for a Node.
* function Node(val, next, random) {
* this.val = val;
* this.next = next;
* this.random = random;
* };
*/
// 返回random指向的copy中的node
// 严格比较
function findrandomStrict(p,pNext,copyhead){
var copy=copyhead;
// copy链的0号结点和1号结点不为空
while(copy!==null&©.next!==null){
// 如果copy链中0,1结点中的值等于原链对应结点的值
if(copy.val===p.val && copy.next.val===pNext.val ){
// 继续判断copy链中2号结点,当原链或copy链中有一个为空,说明不相等
if((pNext.next==null&©.next.next!==null)||(pNext.next!==null&©.next.next==null)){
copy=copy.next;
continue;
}// 继续判断copy链中2号结点,若原链和copy链的2号结点值不相等,则continue
else if(pNext.next!==null&©.next.next!==null){
if(copy.next.next.val!==pNext.next.val){
copy=copy.next;
continue;
}
// 继续判断copy链中3号结点,当原链或copy链中有一个为空,说明不相等
else if((pNext.next.next==null&©.next.next.next!==null)||(pNext.next.next!==null&©.next.next.next==null)) {
copy=copy.next;
continue;
}
// 继续判断copy链中3号结点,若原链和copy链的3号结点值不相等,则continue
else if(pNext.next.next!==null&©.next.next.next!==null&©.next.next.next.val!==pNext.next.next.val){
copy=copy.next;
continue;
}
}
return copy;
}
copy=copy.next;
}
return null;
}
// 返回random指向的copy中的node
function findrandomEasy(p,copyhead){
var copy=copyhead;
while(copy!=null){
if(copy.val==p.val){
return copy;
}
copy=copy.next;
}
return null;
}
function findrandom(p,pNext,copyhead){
var copy=copyhead;
if(p&&pNext){
return findrandomStrict(p,pNext,copyhead);
}
// 如果pnext等于null,说明p指向的是链表的最后一个结点
else if(pNext==null){
while(copy.next!=null){
copy=copy.next;
}
return copy;
}else{
return findrandomEasy(p,copyhead);
}
}
/**
* @param {Node} head
* @return {Node}
*/
var copyRandomList = function(head) {
var p=head;
if(p==null){
return null;
}
// 先复制前两项
var copy=new Node();
var copyHead=copy;
while(p!=null){
if(p.next!=null){
copy.next=new Node();
}else{
copy.next=null;
}
copy.val=p.val;
copy.random=null;
p=p.next;
copy=copy.next;
}
// 复制random
p=head;
copy=copyHead;
while(p!==null){
if(p.random!==null){
copy.random=findrandom(p.random,p.random.next,copyHead);
}
copy=copy.next;
p=p.next;
}
return copyHead;
};
然后是正确答案,原地修改链表,然后将链表拆分
/**
* // 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) {
if(head==null){
return head;
}
// 1-2-3-4 ---->> 1-1'-2-2'-3-3'-4-4'
var p=head;
while(p!=null){
var node=new Node(p.val);
node.next=p.next;
p.next=node;
p=p.next.next;
}
//完成链表复制节点的随机指针复制
p=head;
while(p!=null){
if(p.random!=null){
p.next.random=p.random.next;
}
p=p.next.next;
}
//将链表一分为二
var copyhead=head.next;
var copy=head.next;
p=head;
while(p!=null){
p.next=p.next.next;
p=p.next;
if(copy.next!=null){
copy.next=copy.next.next;
copy=copy.next;
}
}
return copyhead;
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通