-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTreeDepthFirstSearch.py
More file actions
395 lines (274 loc) · 10.4 KB
/
TreeDepthFirstSearch.py
File metadata and controls
395 lines (274 loc) · 10.4 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
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
# Binary Tree Path Sum
import math
from re import S
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
def has_path(root, sum):
if root is None:
return False
if root.val == sum and root.left is None and root.right is None:
return True
return has_path(root.left, sum - root.val) or has_path(root.right, sum - root.val)
def main():
root = TreeNode(12)
root.left = TreeNode(7)
root.right = TreeNode(1)
root.left.left = TreeNode(9)
root.right.left = TreeNode(10)
root.right.right = TreeNode(5)
print("Tree has path: " + str(has_path(root, 23)))
print("Tree has path: " + str(has_path(root, 16)))
main()
# All Paths for a Sum
'''
Given a binary tree and a number S,
find all paths from root-to-leaf such that the
sum of all the node values of each path equals S.
'''
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
def find_paths(root, sum):
allPaths = []
find_paths_helper(root, sum, [], allPaths)
return allPaths
def find_paths_helper(root, sum, currentPath, allPaths):
if root == None:
return
currentPath.append(root.val)
if root.val == sum and root.left == None and root.right == None:
allPaths.append(list(currentPath))
else:
find_paths_helper(root.left, sum - root.val, currentPath, allPaths)
find_paths_helper(root.right, sum - root.val, currentPath, allPaths)
# remove last node visited from the call stack
currentPath.pop()
def main():
root = TreeNode(12)
root.left = TreeNode(7)
root.right = TreeNode(1)
root.left.left = TreeNode(4)
root.right.left = TreeNode(10)
root.right.right = TreeNode(5)
sum = 23
print("Tree paths with sum " + str(sum) +
": " + str(find_paths(root, sum)))
main()
# Sum of Path Numbers
'''
Given a binary tree where each node can only have a digit (0-9) value,
each root-to-leaf path will represent a number.
Find the total sum of all the numbers represented by all paths.
'''
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
def find_sum_of_path_numbers(root):
# TODO: Write your code here
totalSum = 0
return find_sum_of_path_numbers_helper(root, "", totalSum)
def find_sum_of_path_numbers_helper(root, currentNumber, sum):
if root == None:
return 0
currentNumber += str(root.val)
if root.left == None and root.right == None:
sum += int(currentNumber)
return sum
# not necessary to delete the last letter from the string
# currentNumber = currentNumber[:len(currentNumber)-1]
return find_sum_of_path_numbers_helper(root.left, currentNumber, sum) + find_sum_of_path_numbers_helper(root.right, currentNumber, sum)
def main():
root = TreeNode(1)
root.left = TreeNode(0)
root.right = TreeNode(1)
root.left.left = TreeNode(1)
root.right.left = TreeNode(6)
root.right.right = TreeNode(5)
print("Total Sum of Path Numbers: " + str(find_sum_of_path_numbers(root)))
main()
# Path With Given Sequence
"""
Given a binary tree and a number sequence,
find if the sequence is present as a root-to-leaf path in the given tree.
"""
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
def find_path(root, sequence):
return find_path_helper(root, "", sequence)
def find_path_helper(root, currentString, sequence):
if root == None:
return False
currentString += str(root.val)
if root.left == None and root.right == None:
currentSequence = list(currentString)
currentSequence = [int(x) for x in currentSequence]
print(currentSequence)
return currentSequence == sequence
return find_path_helper(root.left, currentString, sequence) or find_path_helper(root.right, currentString, sequence)
def main():
root = TreeNode(1)
root.left = TreeNode(0)
root.right = TreeNode(1)
root.left.left = TreeNode(1)
root.right.left = TreeNode(6)
root.right.right = TreeNode(5)
print("Tree has path sequence: " + str(find_path(root, [1, 0, 7])))
print("Tree has path sequence: " + str(find_path(root, [1, 1, 6])))
main()
# Count Paths for a Sum
'''
Given a binary tree and a number S,
find all paths in the tree such that the sum of all the node values of each path equals S.
Please note that the paths can start or end at any node but all paths must follow direction
from parent to child (top to bottom).
'''
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
def count_paths(root, S):
return count_paths_recursive(root, S, [])
def count_paths_recursive(currentNode, S, currentPath):
if currentNode is None:
return 0
# add the current node to the path
currentPath.append(currentNode.val)
pathCount, pathSum = 0, 0
# find the sums of all sub-paths in the current path list
for i in range(len(currentPath)-1, -1, -1):
pathSum += currentPath[i]
# if the sum of any sub-path is equal to 'S' we increment our path count.
if pathSum == S:
pathCount += 1
# traverse the left sub-tree
pathCount += count_paths_recursive(currentNode.left, S, currentPath)
# traverse the right sub-tree
pathCount += count_paths_recursive(currentNode.right, S, currentPath)
# remove the current node from the path to backtrack
# we need to remove the current node while we are going up the recursive call stack
del currentPath[-1]
return pathCount
def main():
root = TreeNode(12)
root.left = TreeNode(7)
root.right = TreeNode(1)
root.left.left = TreeNode(4)
root.right.left = TreeNode(10)
root.right.right = TreeNode(5)
# 11
print("Tree has paths: " + str(count_paths(root, 23)))
main()
# Tree Diameter
"""
Given a binary tree,
find the length of its diameter.
The diameter of a tree is the number of nodes on the longest path
between any two leaf nodes.
The diameter of a tree may or may not pass through the root.
Note: You can always assume that there are at least
two leaf nodes in the given tree.
"""
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class TreeDiameter:
def __init__(self):
self.treeDiameter = 0
def find_diameter(self, root):
self.calculate_height(root)
return self.treeDiameter
def calculate_height(self, currentNode):
if currentNode is None:
return 0
leftTreeHeight = self.calculate_height(currentNode.left)
rightTreeHeight = self.calculate_height(currentNode.right)
# if the current node doesn't have a left or right subtree, we can't have
# a path passing through it, since we need a leaf node on each side
if leftTreeHeight != 0 and rightTreeHeight != 0:
# diameter at the current node will be equal to the height of left subtree +
# the height of right sub-trees + '1' for the current node
diameter = leftTreeHeight + rightTreeHeight + 1
# update the global tree diameter
self.treeDiameter = max(self.treeDiameter, diameter)
# height of the current node will be equal to the maximum of the heights of
# left or right subtrees plus '1' for the current node
return max(leftTreeHeight, rightTreeHeight) + 1
def main():
treeDiameter = TreeDiameter()
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.right.left = TreeNode(5)
root.right.right = TreeNode(6)
print("Tree Diameter: " + str(treeDiameter.find_diameter(root)))
root.left.left = None
root.right.left.left = TreeNode(7)
root.right.left.right = TreeNode(8)
root.right.right.left = TreeNode(9)
root.right.left.right.left = TreeNode(10)
root.right.right.left.left = TreeNode(11)
print("Tree Diameter: " + str(treeDiameter.find_diameter(root)))
main()
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class MaximumPathSum:
def find_maximum_path_sum(self, root):
self.globalMaximumSum = -math.inf
self.find_maximum_path_sum_recursive(root)
return self.globalMaximumSum
def find_maximum_path_sum_recursive(self, currentNode):
if currentNode is None:
return 0
maxPathSumFromLeft = self.find_maximum_path_sum_recursive(
currentNode.left)
maxPathSumFromRight = self.find_maximum_path_sum_recursive(
currentNode.right)
# ignore paths with negative sums, since we need to find the maximum sum we should
# ignore any path which has an overall negative sum.
maxPathSumFromLeft = max(maxPathSumFromLeft, 0)
maxPathSumFromRight = max(maxPathSumFromRight, 0)
# maximum path sum at the current node will be equal to the sum from the left subtree +
# the sum from right subtree + val of current node
localMaximumSum = maxPathSumFromLeft + maxPathSumFromRight + currentNode.val
# update the global maximum sum
self.globalMaximumSum = max(self.globalMaximumSum, localMaximumSum)
# maximum sum of any path from the current node will be equal to the maximum of
# the sums from left or right subtrees plus the value of the current node
return max(maxPathSumFromLeft, maxPathSumFromRight) + currentNode.val
def main():
maximumPathSum = MaximumPathSum()
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
print("Maximum Path Sum: " + str(maximumPathSum.find_maximum_path_sum(root)))
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
root.right.left = TreeNode(5)
root.right.right = TreeNode(6)
root.right.left.left = TreeNode(7)
root.right.left.right = TreeNode(8)
root.right.right.left = TreeNode(9)
print("Maximum Path Sum: " + str(maximumPathSum.find_maximum_path_sum(root)))
root = TreeNode(-1)
root.left = TreeNode(-3)
print("Maximum Path Sum: " + str(maximumPathSum.find_maximum_path_sum(root)))
main()
# comment added
# one more comment