-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproblem-3-medium.py
More file actions
143 lines (116 loc) · 4.2 KB
/
Copy pathproblem-3-medium.py
File metadata and controls
143 lines (116 loc) · 4.2 KB
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
import json
"""
This problem was asked by Google.
Given the root to a binary tree, implement serialize(root), which serializes
the tree into a string, and deserialize(s), which deserializes the string
back into the tree.
For example, given the following Node class
"""
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
"""
The following test should pass:
node = Node('root', Node('left', Node('left.left')), Node('right'))
assert deserialize(serialize(node)).left.left.val == 'left.left'
"""
node = Node('root', Node('left', Node('left.left')), Node('right'))
def serialize(root) -> str:
serialized = dict()
serialized["val"] = root.val
serialized["left"] = serialize(root.left) if root.left != None else None
serialized["right"] = serialize(root.right) if root.right != None else None
return json.dumps(serialized)
def deserialize(s) -> Node:
deserialized_json = json.loads(s)
node_left = deserialize(deserialized_json["left"]) if deserialized_json["left"] != None else None
node_right = deserialize(deserialized_json["right"]) if deserialized_json["right"] != None else None
node = Node(deserialized_json["val"], node_left, node_right)
return node
assert deserialize(serialize(node)).left.left.val == 'left.left'
"""
BONUS: This attempt does not use JSON but instead creates a printable String
representation which can then be converted back to the Node class
"""
def bonus_serialize(root) -> str:
"""
we begin by appending the class name and root value of the Node.
"""
serialized = f"Node({root.val}, "
while True:
"""
we check if the left branch exists, and if it does we use recursion
to go down the branch. if not, we append None instead to later aid
us with the deserialization. we loop through this process until all
branches are serialized.
"""
if root.left != None:
serialized += f"{serialize(root.left)}, "
else:
serialized += "None, "
"""
we do the same for the right branch
"""
if root.right != None:
serialized += serialize(root.right)
else:
serialized += "None"
break
"""
we close the Node and return the final string.
"""
serialized += ")"
return serialized
"""
a function which looks for parentheses pairs and then returns a sorted list
of tupils and the indexes of each pair.
"""
def find_parens(s):
toret = {}
pstack = []
for i, c in enumerate(s):
if c == '(':
pstack.append(i)
elif c == ')':
toret[pstack.pop()] = i
return sorted(list(toret.items()))
def bonus_deserialize(s) -> Node:
"""
get the index of each parantheses in pairs, we will use this to seperate
the right and left branches
"""
found_peren_list = find_parens(s)
"""
since the tupils are ordered, the first tupil is the root of the binary
tree. We thus use those indecies to slice the string
"""
node = Node(s[found_peren_list[0][0]+1:found_peren_list[0][1]].split(", ")[0])
left = []
right = []
is_left = True
"""
we remove 1 from the usual range so that we may add 1 to the index to
compare the current and next index and whether the closing paren is less
or greater than to the one after.
as soon as the paren at index <index> is less than the one at index
<index + 1>, we know the next set of tupils represent the right branch.
"""
for index in range(len(found_peren_list)-1):
if found_peren_list[index][1] < found_peren_list[index+1][1]:
is_left = False
if is_left:
left.append(found_peren_list[index +1])
else:
right.append(found_peren_list[index +1])
"""
we use the first tupil in the list and pass it into the desserialize
method. we can do this as the first element in each list is the root
of each branch.
"""
if len(left) != 0:
node.left = deserialize(s[left[0][0]:left[0][1]+1])
if len(right) != 0:
node.right = deserialize(s[right[0][0]:right[0][1]+1])
return node