-
Notifications
You must be signed in to change notification settings - Fork 1
/
copy-list-with-random-pointer.py
148 lines (131 loc) · 4.93 KB
/
copy-list-with-random-pointer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# coding=utf-8
# Definition for singly-linked list with a random pointer.
class RandomListNode(object):
def __init__(self, x):
self.label = x
self.next = None
self.random = None
class Solution(object):
def __init__(self):
# Creating a visited dictionary to hold old node reference as "key" and new node reference as the "value"
self.visited = {}
def copyRandomList(self, head):
"""
:type head: RandomListNode
:rtype: RandomListNode
"""
if not head:
return
node_copy_dict = {}
current = head
dummy = RandomListNode(0)
head_copy = RandomListNode(head.label)
node_copy_dict[head] = head_copy
dummy.next = head_copy
pre = dummy
while current:
if current not in node_copy_dict:
current_copy = RandomListNode(current.label)
node_copy_dict[current] = current_copy
else:
current_copy = node_copy_dict[current]
random = current.random
if random:
if random not in node_copy_dict:
random_copy = RandomListNode(random.label)
node_copy_dict[random] = random_copy
else:
random_copy = node_copy_dict.get(random)
current_copy.random = random_copy
after = current.next
if after:
if after not in node_copy_dict:
after_copy = RandomListNode(after.label)
node_copy_dict[after] = after_copy
else:
after_copy = node_copy_dict.get(after)
current_copy.next = after_copy
current = after
return dummy.next
def getClonedNode(self, node):
# If node exists then
if node:
# Check if its in the visited dictionary
if node in self.visited:
# If its in the visited dictionary then return the new node reference from the dictionary
return self.visited[node]
else:
# Otherwise create a new node, save the reference in the visited dictionary and return it.
self.visited[node] = RandomListNode(node.label)
return self.visited[node]
return None
def copyRandomList1(self, head):
"""
:type head: RandomListNode
:rtype: RandomListNode
"""
if not head:
return head
old_node = head
# Creating the new head node.
new_node = RandomListNode(old_node.label)
self.visited[old_node] = new_node
# Iterate on the linked list until all nodes are cloned.
while old_node != None:
# Get the clones of the nodes referenced by random and next pointers.
new_node.random = self.getClonedNode(old_node.random)
new_node.next = self.getClonedNode(old_node.next)
# Move one step ahead in the linked list.
old_node = old_node.next
new_node = new_node.next
return self.visited[head]
def copyRandomList2(self, head):
"""
把复制节点放在每一个源节点的后面
然后从头遍历新的链表,取出复制后的部分
解释参考链接
https://leetcode.com/problems/copy-list-with-random-pointer/solution/
:param head:
:return:
"""
if not head:
return
current = head
# 复制原链表的每个节点,形成 A->A'->B->B'->C->C'
while current:
post = current.next
current_copy = RandomListNode(current.label)
current.next = current_copy
current_copy.next = post
current = post
# 修改复制节点的random指针,改为源节点的random指针的复制节点
current = head
while current:
if current.random:
current.next.random = current.random.next
current = current.next.next
# 从head链表里挑出复制出来的新节点
ptr_old_list = head # A->B->C
ptr_new_list = head.next # A'->B'->C'
head_new = head.next
while ptr_old_list:
ptr_old_list.next = ptr_old_list.next.next
ptr_new_list.next = ptr_new_list.next.next if ptr_new_list.next else None
ptr_old_list = ptr_old_list.next
ptr_new_list = ptr_new_list.next
return head_new
def copyRandomList3(self, head):
"""
用递归方法,对next和random指针递归
:param head:
:return:
"""
if not head:
return
if head in self.visited:
return self.visited[head]
node = RandomListNode(head.label)
self.visited[head] = node
node.next = self.copyRandomList3(head.next)
node.random = self.copyRandomList3(head.random)
return node