题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
题目分析
1.如果链表为空链表,则返回本身即可2.如果非空 需要进行复制操作,如果没有特殊指针,只需要复制next我相信大家都能很快做出来,但是加上特殊指针这就需要一定技巧,因为特殊指针随便指,而你每次找特殊指针所指的节点都需要从头开始遍历找起,这显然复杂度高达O(n²)下面介绍一个巧妙地思想方法:如图
首先第一步 复制原来的链表,顺次连接形成新链表
1 cloNode = pHead2 while cloNode:3 #完成第一步的核心操作4 node = RandomListNode(cloNode.label)5 node.next = cloNode.next6 cloNode.next = node78 cloNode = node.next #下一次操作
第二步,利用原节点的random指向,来用复制的相应节点的random
1 cloNode = pHead2 while cloNode:3 node = cloNode.next #指向复制的结点4 if cloNode.random: #如果原节点有特殊指针5 node.random = cloNode.random.next #则复制的节点的特殊指针指向原节点的特殊指针指向的下一个值 看图更好理解一些6 cloNode = node.next
最后一步,将复制好的链表拆分出来,或者说将 偶数位的节点重新拆分合成新的链表,得到的就是复制的链表
1 cloNode = pHead2 pHead = pHead.next3 while cloNode.next:4 #完成第三步的核心操作 此时节点指向隔了一个节点的节点5 node = cloNode.next6 cloNode.next = node.next78 cloNode = node #下一个节点的操作
这个操作其实就是将两个链表顺次全都拆分出来,一个很关键的步骤 pHead = pHead.next 如果没有这句话,最后得到的pHead就是原链表的开头了。
总程序如下:
1# -*- coding:utf-8 -*- 2# class RandomListNode: 3# def __init__(self, x): 4# self.label = x 5# self.next = None 6# self.random = None 7class Solution: 8 # 返回 RandomListNode 9 def Clone(self, pHead):10 # write code here11 if not pHead:12 return pHead13 cloNode = pHead14 while cloNode:15 node = RandomListNode(cloNode.label)16 node.next = cloNode.next17 cloNode.next = node18 cloNode = node.next19 cloNode = pHead20 while cloNode:21 node = cloNode.next22 if cloNode.random:23 node.random = cloNode.random.next24 cloNode = node.next25 cloNode = pHead26 pHead = pHead.next27 while cloNode.next:28 node = cloNode.next29 cloNode.next = node.next30 cloNode = node31 return pHead