「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
给你一个长度为
n的链表,每个节点包含一个额外增加的随机指针random,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
示例:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
题意可分解为两部分:其一复制链表,其二复制的链表带有随机指向
接下来选择解题方法,理清思路:
-
首先第一步,只考虑进行原链表的复制操作:
因为是深拷贝,所以我们需要创建一个新的链表用于存储复制后的节点
if(!head) return null; let p = head, //p指向链表的头节点 q; //声明一个变量p,后面用于存储新创建的新的链表 //执行赋值操作 while(p){ q = new ListNode(p.val); //直接将p的val传入 q.next = p.next; //将p.next的指向赋值于q.next,令其指向相同的下一个节点 q.random = p.random; //接下来,切断原链表,将q节点依次插入到父节点p节点的后面 p.next = q; //移动变量p的指针指向,进行接下来的循环操作 p = q.next }在这里,一定要搞清楚,①指针的指向问题,②指针的指向切换问题
-
完成原链表的赋值操作后,重新让变量
p指向head.next(此时的head已经是包含双节点的链表),接下来调整q链表中每个节点random的指向p = head.next; while(p){ p.random && (p.random = p.random.next); (p = p.next) && (p = p.next); //等同于下面的if语句 //if(p.next) p = p.next.next }注意p = p.next.next需要满足的条件
-
完成
random随即指针的指向后,接下来进行拆分链表操作,分成原链表和克隆节点链表p = q = head.next; //将p和q同时指向head.next节点,先锁定head.next节点,避免丢失,同时p来作为q的链表头节点,q为定位指针(二者可以互换?) while(q.next){ head.next = head.next.next; //改变head节点的指向 q.next = q.next.next; //以上两步改变head.next和q.next的指向,下面两步是移动head和q的指向,后移一步 head = head.next; q = q.next; } //最后需要重置head.next为null head.next = null; return p;调整指针的指向和指针的next赋值,最容易搞混
👆 👆 以上就是个人对【复制带随机指针的链表】的代码解法和方法解读。
迷惑重重,就用蜡笔头,一键三连哟!!!
完成代码请移步: 稍后添加