-
Notifications
You must be signed in to change notification settings - Fork 7
/
All Kinds Of Node Depths.py
211 lines (161 loc) · 6.3 KB
/
All Kinds Of Node Depths.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
"""
All kinds of Node Depths o ☆
The distance between a node in a Binary Tree and the tree's root is called the node's depth.
Write a function that takes in a Binary Tree and returns the sum of all of its subtrees' nodes' depths.
Each BinaryTree node has an integer value , a left child node, and a right child node. Children nodes can either be
BinaryTree nodes themselves or None / null.
Sample Input
tree = 1
/ \
2 3
/ \ / \
4 5 6 7
/ \
8 9
Sample Output
26
// The sum of the root tree's node depths is 16.
// The sum of the tree rooted at 2's node depths is 6.
// The sum of the tree rooted at 3's node depths is 2.
// The sum of the tree rooted at 4's node depths is 2.
// Summing all of these sums yields 26.
"""
# SOLUTION 1
# Average case: when the tree is balanced
# O(nlog(n)) time | och) space where n is the number of nodes in
# the Binary Tree and h is the height of the Binary Tree
def allKindsOfNodeDepths(root):
sumOfAllDepths = 0
stack = [root]
while len(stack) > 0:
node = stack.pop()
if node is None:
continue
sumOfAllDepths += nodeDepths(node)
stack.append(node.left)
stack.append(node.right)
return sumOfAllDepths
def nodeDepths(node, depth=0):
if node is None:
return 0
return depth + nodeDepths(node.left, depth + 1) + nodeDepths(node.right, depth + 1)
# This is the class of the input binary tree.
class BinaryTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
# SOLUTION 2
# Average case: when the tree is balanced
# O(nlog(n)) time | (h) space where n is the number of nodes in
# the Binary Tree and h is the height of the Binary Tree
def allKindsOfNodeDepths(root):
if root is None:
return 0
return allKindsOfNodeDepths(root.left) + allKindsOfNodeDepths(root.right) + nodeDepths(root)
def nodeDepths(node, depth=0):
if node is None:
return 0
return depth + nodeDepths(node.left, depth + 1) + nodeDepths(node.right, depth + 1)
class BinaryTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
# SOLUTION 3
# Average case: when the tree is balanced
# O(n) time | O(n) space where n is the number of nodes in the Binary Tree
def allKindsOfNodeDepths(root):
nodeCounts = {}
addNodeCounts(root, nodeCounts)
nodeDepths = {}
addNodeDepths(root, nodeDepths, nodeCounts)
return sumAllNodeDepths(root, nodeDepths)
def sumAllNodeDepths(node, nodeDepths):
if node is None:
return 0
return sumAllNodeDepths(node.left, nodeDepths) + sumAllNodeDepths(node.right, nodeDepths) + nodeDepths[node]
def addNodeDepths(node, nodeDepths, nodeCounts):
nodeDepths[node] = 0
if node.left is not None:
addNodeDepths(node.left, nodeDepths, nodeCounts)
nodeDepths[node] += nodeDepths[node.left] + nodeCounts[node.left]
if node.right is not None:
addNodeDepths(node.right, nodeDepths, nodeCounts)
nodeDepths[node] += nodeDepths[node.right] + nodeCounts[node.right]
def addNodeCounts(node, nodeCounts):
nodeCounts[node] = 1
if node.left is not None:
addNodeCounts(node.left, nodeCounts)
nodeCounts[node] += nodeCounts[node.left]
if node.right is not None:
addNodeCounts(node.right, nodeCounts)
nodeCounts[node] += nodeCounts[node.right]
# This is the class of the input binary tree.
class BinaryTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
# SOLUTION 4
# Average case: when the tree is balanced
# O(n) time | 0(h) space where n is the number of nodes in
# the Binary Tree and h is the height of the Binary Tree
def allKindsOfNodeDepths(root):
return getTreeInfo(root).sumOfAllDepths
def getTreeInfo(tree):
if tree is None:
return TreeInfo(0, 0, 0)
leftTreeInfo = getTreeInfo(tree.left)
rightTreeInfo = getTreeInfo(tree.right)
sumOfLeftDepths = leftTreeInfo.sumOfDepths + leftTreeInfo.numNodesInTree
sumOfRightDepths = rightTreeInfo.sumOfDepths + rightTreeInfo.numNodesInTree
numNodesInTree = 1 + leftTreeInfo.numNodesInTree + rightTreeInfo.numNodesInTree
sumOfDepths = sumOfLeftDepths + sumOfRightDepths
sumOfAllDepths = sumOfDepths + leftTreeInfo.sumOfAllDepths + rightTreeInfo.sumOfAllDepths
return TreeInfo(numNodesInTree, sumOfDepths, sumOfAllDepths)
class TreeInfo:
def __init__(self, numNodesInTree, sumOfDepths, sumOfAllDepths):
self.numNodesInTree = numNodesInTree
self.sumOfDepths = sumOfDepths
self.sumOfAllDepths = sumOfAllDepths
# This is the class of the input binary tree.
class BinaryTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
# SOLUTION 5
# Average case: when the tree is balanced
# O(n) time | 0(h) space where n is the number of nodes in
# the Binary Tree and h is the height of the Binary Tree
def allKindsOfNodeDepths(root, depthSum=0, depth=0):
if root is None:
return 0
depthSum += depth
return (
depthSum
+ allKindsOfNodeDepths(root.left, depthSum, depth + 1)
+ allKindsOfNodeDepths(root.right, depthSum, depth + 1)
)
class BinaryTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
# SOLUTION 6
# Average case: when the tree is balanced
# O(n) time | (h) space where n is the number of nodes in
# the Binary Tree and h is the height of the Binary Tree
def allKindsOfNodeDepths(root, depth=0):
if root is None:
return 0
# Formula to calculate 1 + 2 + 3 + ... + depth - 1 + depth
depthSum = (depth * (depth + 1)) / 2
return depthSum + allKindsOfNodeDepths(root.left, depth + 1) + allKindsOfNodeDepths(root.right, depth + 1)
# This is the class of the input binary tree.
class BinaryTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None