输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。
V1 – hash + 双循环
# -*- 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):
# loop1 : initial
myHead = RandomListNode(0)
cur = myHead
tmpHead = pHead
myset = {} #存放结点的 【原结点地址: 索引】
ls = [] #存放结点 【索引: 新结点地址】
i = 0
while tmpHead:
cur.next = RandomListNode(tmpHead.label)
myset[tmpHead] = i
ls.append(cur.next)
i += 1
cur = cur.next
tmpHead = tmpHead.next
# loop2 : random alignment
i = 0
cur = myHead.next
while pHead:
if pHead.random:
index = myset[pHead.random]
cur.random = ls[index]
pHead = pHead.next
cur = cur.next
return myHead.next
评价:
第一版的代码使用了dict来记录,实现了hash的功能,这样使得整个算法复杂度为O(n),是比较快的。
v2 – 三循环
v3 – 递归
错误示范1
这个代码是完全错误的哈,这个错误是因为random指向了和原来相同的结点,所以虽然可以AC,但是就是错误的。
错误示范2
这个代码是C++的,最终生成的链表并不是完全正确的,只是random指向了具有正确value的结点,即:返回值是准确,可以AC,但是并不是同一个结点。