題目描述
輸入一個復雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果為復制后復雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
題目分析
1.如果鏈表為空鏈表,則返回本身即可
2.如果非空 需要進行復制操作,如果沒有特殊指針,只需要復制next我相信大家都能很快做出來,但是加上特殊指針這就需要一定技巧,因為特殊指針隨便指,而你每次找特殊指針所指的節點都需要從頭開始遍歷找起,這顯然復雜度高達O(n²)
下面介紹一個巧妙地思想方法:
如圖
首先第一步 復制原來的鏈表,順次連接形成新鏈表

cloNode = pHead
while cloNode:
#完成第一步的核心操作
node = RandomListNode(cloNode.label)
node.next = cloNode.next
cloNode.next = node
cloNode = node.next #下一次操作
第二步,利用原節點的random指向,來用復制的相應節點的random

cloNode = pHead
while cloNode:
node = cloNode.next #指向復制的結點
if cloNode.random: #如果原節點有特殊指針
node.random = cloNode.random.next #則復制的節點的特殊指針指向原節點的特殊指針指向的下一個值 看圖更好理解一些
cloNode = node.next
最后一步,將復制好的鏈表拆分出來,或者說將 偶數位的節點重新拆分合成新的鏈表,得到的就是復制的鏈表

cloNode = pHead
pHead = pHead.next
while cloNode.next:
#完成第三步的核心操作 此時節點指向隔了一個節點的節點
node = cloNode.next
cloNode.next = node.next
cloNode = node #下一個節點的操作
這個操作其實就是將兩個鏈表順次全都拆分出來,一個很關鍵的步驟 pHead = pHead.next 如果沒有這句話,最后得到的pHead就是原鏈表的開頭了。
總程序如下:
# -*- 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 not pHead:
return pHead
cloNode = pHead
while cloNode:
node = RandomListNode(cloNode.label)
node.next = cloNode.next
cloNode.next = node
cloNode = node.next
cloNode = pHead
while cloNode:
node = cloNode.next
if cloNode.random:
node.random = cloNode.random.next
cloNode = node.next
cloNode = pHead
pHead = pHead.next
while cloNode.next:
node = cloNode.next
cloNode.next = node.next
cloNode = node
return pHead
