体能修复7-编程-剑指offer-JZ35 复杂链表的复制

描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。

示例

  输入:{1,2,3,4,5,3,5,#,2,#} 

  输出:{1,2,3,4,5,3,5,#,2,#} 

解析

我们将链表分为两段,前半部分{1,2,3,4,5}为ListNode,后半部分{3,5,#,2,#}是随机指针域表示。

以上示例前半部分可以表示链表为的ListNode:1->2->3->4->5

后半部分,3,5,#,2,#分别的表示为1的位置指向3,2的位置指向5,3的位置指向null,4的位置指向2,5的位置指向null

如下图:

思路 

因为这是一道算法题,所以出题人不允许直接返回非pHead。

此算法分为三个部分:

1. forward复制label(val),并且将复制值按在原指针后面

2. 创建复制的random指针

3. 将复制指针从原指针剥离

接下来,详细讲解

1. forward复制label(val),并且将复制值按在原指针后面

若原链表为:

排除random指针带来的干扰,将原链表视为只有next指针的链表: 

则,完成1. 复制指针并将其插入原指针对应位置后 操作后链表会变为:

 

此过程,拆解为:

(1) clone = RandomListNode(cur.label)

 

(2) clone.next = cur.next

 

 

(3) cur.next = clone
 
(4) cur = clone.next
 

 

2.创建复制的random指针

接1. 操作 将链表还原成:

则,完成2. 创建复制的random指针后 操作后链表会变为: 

 

此过程,拆解为:

若求 橙色1(cur.next)的random指针橙色3(cur.next.random),已知蓝色1(指针cur) 的random指针是蓝色3(cur.random),且蓝色指针相对于橙色指针是.next。

所以 cur.next.random = cur.random.next

接着cur走两步,从蓝色的1走到蓝色的2

cur = cur.next.next

 

3. 将复制指针从原指针剥离

则,完成3. 将复制指针从原指针剥离后 操作后链表会变为:

(1) cur = pHead

newHead = pHead.next

 

将pHead与newHead分开

(2) temp = cur.next 
    cur.next = temp.next
    cur = temp

 代码

# -*- coding:utf-8 -*-
# class RandomListNode:
#     def __init__(self, x):
#         self.label = x
#         self.next = None
#         self.random = None
class Solution:
    # 返回 RandomListNode
    def Clone(self, pHead):
        # write code here
        if pHead == None:
            return None
        # 1. copy label
        cur = pHead
        while cur:
            clone = RandomListNode(cur.label)
            clone.next = cur.next
            cur.next = clone
            cur = clone.next
        # 2. create random
        cur = pHead
        while cur:
            if cur.random:
                cur.next.random = cur.random.next
            cur = cur.next.next
        # 3. divide RandomListNode
        cur = pHead
        newHead = pHead.next
        while cur.next:
            temp = cur.next
            cur.next = temp.next
            cur = temp
                
        return newHead

结果

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值