題目描述
輸入一個復雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果為復制后復雜鏈表的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