# Definition for singly-linked list with a random pointer.# class RandomListNode(object):# def __init__(self, x):# self.label = x# self.next = None# self.random = NoneclassSolution(object):defcopyRandomList(self,head):""" :type head: RandomListNode :rtype: RandomListNode """if head isNone:return head dummy =RandomListNode(-1) cur = dummy curOld = head mapping ={} mapping[None]=Nonewhile(curOld): cur.next =RandomListNode(curOld.label) mapping[curOld]= cur.next cur = cur.next curOld = curOld.next cur = dummy curOld = headwhile(curOld): cur.next.random = mapping[curOld.random] # when random is None, traversing linked list won't add none in the dictionary, we need to do it manually
cur = cur.next curOld = curOld.nextreturn dummy.next'''
Use dictionary to map old nodes (as key) to new nodes (as value). So that we could traverse old & new list together and know which new list node should be set as random reference.
# Definition for singly-linked list with a random pointer.# class RandomListNode(object):# def __init__(self, x):# self.label = x# self.next = None# self.random = NoneclassSolution(object):defcopyRandomList(self,head):""" :type head: RandomListNode :rtype: RandomListNode """if head isNone:return head cur = headwhile(cur): nextNode = cur.next cur.next = RandomListNode(cur.label) # 5)用前后相邻顺序替代 dictionary 的映射关系,降低额外空间的占用;遇到要优化的算法时,尝试转换思路,什么东西可以【在功能上替代】传统的简单思路
cur.next.next = nextNode cur = nextNode cur = head while(cur):if cur.random:# 1) any next in linked list should be validated; cur.next.random = cur.random.next # 2) 如果一边加 random 一边去掉新旧之间的 link,会导致后面的新 node 指前面 新 node 时 找不到了,所以必须用两个循环来处理
cur = cur.next.next # 3)修改代码时,时刻double check 逻辑是否正确 cur = head dummy =RandomListNode(-1) newCur = dummywhile(cur): newCur.next = cur.next # 4)跳着连接时,先处理中间值再对前后处理 cur.next = cur.next.next cur = cur.next newCur = newCur.nextreturn dummy.next
See 1) 2) 3) 4) 5) in the code comments
To summary, by inserting new node after old node, we could replace the mapping relationship. The core algorithm is :
if cur.random:# 1) any next in linked list should be validated; cur.next.random = cur.random.next # 2) 如果一边加 random 一边去掉新旧之间的 link,会导致后面的新 node 指前面 新 node 时 找不到了,所以必须用两个循环来处理