原题地址:https://oj.leetcode.com/problems/copy-list-with-random-pointer/
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
这题要求:将一个链表进行深度拷贝,链表中的节点有一个random属性,指向链表中的任意节点
刚看到这题,我想到用数组来保存每个节点,拷贝random时,再用一个数组来表示拷贝的节点,两个链表是一一对应的。这样当需要拷贝random属性时,仅仅需要查询原节点的random在原数组中的索引。我的第一个解法如下,超时了。
# Definition for singly-linked list with a random pointer.
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# @param head, a RandomListNode
# @return a RandomListNode
def copyRandomList(self, head):
arr,newArr = [],[]
tmp = head
while tmp!=None:
arr.append(tmp)
newArr.append(RandomListNode(tmp.label))
tmp = tmp.next
if len(arr) == 0:
return None
for i in range(0,len(newArr)):
if i!=len(newArr)-1:
newArr[i].next = newArr[i+1]
if arr[i].random:
newArr[i].random = newArr[arr.index(arr[i].random)]
return newArr[0]
超时的原因是如下语句执行起来耗时arr.index(arr[i].random)
那么该如何用线性时间查找索引呢,就是利用hash表,hash表保存node对象以及其索引,修改后的代码如下所示:
# Definition for singly-linked list with a random pointer.
class RandomListNode:
def __init__(self, x):
self.label = x
self.next = None
self.random = None
class Solution:
# @param head, a RandomListNode
# @return a RandomListNode
def copyRandomList(self, head):
arr,newArr,map = [],[],{}
tmp = head
i = 0
while tmp!=None:
arr.append(tmp)
newArr.append(RandomListNode(tmp.label))
map[tmp] = i
tmp = tmp.next
i+=1
if len(arr) == 0:
return None
for i in range(0,len(newArr)):
if i!=len(newArr)-1:
newArr[i].next = newArr[i+1]
if arr[i].random:
newArr[i].random = newArr[map[arr[i].random]]
return newArr[0]