25.复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
记录
1.复杂链表
一般链表中的节点有val和next,而复杂链表中的节点还有可能有random,即该节点可能随机指向某个节点。
2.深拷贝
浅拷贝中,当改变拷贝对象的值,被拷贝对象的值也会随之改变;
深拷贝中,当改变拷贝对象的值,被拷贝对象的值不会随之改变。
方法一:
递归。
复杂度:O(n^2)
# -*- 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
newNode = RandomListNode(pHead.label)
newNode.random = pHead.random
newNode.next = self.Clone(pHead.next)
return newNode
方法二:
复杂度:O(n)
# -*- 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):
#常规判空
if not pHead:
return pHead
#第一步,复制所有的节点和next,构造一个新链表
clonenode = pHead
while clonenode:
newnode = RandomListNode(clonenode.label)
newnode.next = clonenode.next
clonenode.next = newnode
clonenode = newnode.next
#第二步,复制所有的random,并添加到第一步的链表中
clonenode = pHead
while clonenode:
newnode = clonenode.next
if clonenode.random:
newnode.random = clonenode.random.next
clonenode = newnode.next
#第三步,将两个链表拆开,实现复杂链表的复制
clonenode = pHead
#指向复制链表的头节点
pHead = pHead.next
while clonenode.next:
newnode = clonenode.next
clonenode.next = newnode.next
clonenode = newnode
return 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
nodeList = [] #节点列表
randomList = [] #random节点列表
labelList = [] #节点值列表
while pHead:
nodeList.append(pHead)
randomList.append(pHead.random)
labelList.append(pHead.label)
pHead = pHead.next
#random节点的索引的列表
labelIndexList = map(lambda c: nodeList.index(c) if c else -1, randomList)
dummy = RandomListNode(0)
pre = dummy
#在节点列表中添加random节点
nodeList=map(lambda c:RandomListNode(c),labelList)
for i in range(len(nodeList)):
if labelIndexList[i] != -1:
nodeList[i].random = nodeList[labelIndexList[i]]
for i in nodeList:
pre.next = i
pre = pre.next
return dummy.next