剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制 - 力扣(LeetCode)

思路:拼接+拆分

考虑构建 原节点 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#返回新链表头节点

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值