思路:拼接+拆分
考虑构建 原节点 1 -> 新节点 1 -> 原节点 2 -> 新节点 2 -> …… 的拼接链表,根据原节点 的random 指向的节点,构造对应新节点 的random 指向的节点。
算法流程:
一:复制各节点,构建拼接链表:设原链表为 node1->node2->node3->... ,构建的拼接链表如下所示:
node1->node1_new->node2->node2_new->node3->...
那么,怎么根据原链表构建新的拼接链表呢?自己思考后看解析,如下所示。
cur=head while cur: tmp=Node(cur.val)#新建一个节点 tmp.next=cur.next cur.next=tmp cur=tmp.next
如果根据原链表(黄色),构造出新节点(蓝色)之间random的指向,那么蓝色的点就是黄色点的复制,接下来只需把蓝色的点拆分下来,我们就把原链表复制了一份。
那么怎么构造新节点(蓝色)之间random的指向?
cur表示原节点(黄色),对应新节点cur.next的随机指向节点为cur.random.next
如cur为节点3(黄),对应的新节点cur.next为3(蓝色),黄色3的random指向节点7(黄色),所以新增加的节点蓝色3的random应指向蓝色节点7(cur.random.next=黄色7.next=蓝色7),搞定
#2.构建各新节点的random指向
cur=head
while cur:
if cur.random:
cur.next.random=cur.random.next
cur=cur.next.next
拆分原链表和 /新链表:
那么怎么链表拆为把黄色链表和蓝色链表?
设置 pre / cur 分别指向原 / 新链表头节点
遍历执行 pre.next = pre.next.next 和 cur.next = cur.next.next 将两链表拆分开。
返回新链表的头节点 res 即可。
只需提交Solution内容
class Node:
def __init__(self,val):
self.val=val;
self.next=None;
self.random=None;
class Solution:
def copyRandomList(self,head):
if not head:#空链表返回空
return None
#1.复制各节点,并构建拼接链表
cur=head
while cur:
tmp=Node(cur.val)#新建一个节点
tmp.next=cur.next
cur.next=tmp
cur=tmp.next
#2.构建各新节点的random指向
cur=head
while cur:
if cur.random:
cur.next.random=cur.random.next
cur=cur.next.next
#3.拆分链表
pre=head
cur=res=head.next
while cur.next:
pre.next=pre.next.next
cur.next=cur.next.next
pre=pre.next
cur=cur.next
pre.next=None#单独处理原链表的尾节点
return res#返回新链表头节点