Skip to content

Commit aa1c853

Browse files
jahir-raihanpre-commit-ci[bot]cclauss
authored
Algorithm to get maximum path sum of a binary tree. (#9414)
* Algorithm to get maximum path sum of a binary tree. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added "TreeNode | None" as traverse method argument type hints to accept both * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added doctest for construct_tree and type hints for TreeNode * Added type hint and doctest * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Preformatted using black * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Organized imports * updating DIRECTORY.md * Apply suggestion from @cclauss --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: cclauss <cclauss@users.noreply.github.com>
1 parent 657c967 commit aa1c853

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@
251251
* [Basic Binary Tree](data_structures/binary_tree/basic_binary_tree.py)
252252
* [Binary Search Tree](data_structures/binary_tree/binary_search_tree.py)
253253
* [Binary Search Tree Recursive](data_structures/binary_tree/binary_search_tree_recursive.py)
254+
* [Binary Tree Maximum Path Sum](data_structures/binary_tree/binary_tree_maximum_path_sum.py)
254255
* [Binary Tree Mirror](data_structures/binary_tree/binary_tree_mirror.py)
255256
* [Binary Tree Node Sum](data_structures/binary_tree/binary_tree_node_sum.py)
256257
* [Binary Tree Path Sum](data_structures/binary_tree/binary_tree_path_sum.py)
@@ -876,6 +877,7 @@
876877
* [Test Factorial](maths/test_factorial.py)
877878
* [Test Prime Check](maths/test_prime_check.py)
878879
* [Three Sum](maths/three_sum.py)
880+
* [Tonelli Shanks](maths/tonelli_shanks.py)
879881
* [Trailing Zeroes](maths/trailing_zeroes.py)
880882
* [Trapezoidal Rule](maths/trapezoidal_rule.py)
881883
* [Triplet Sum](maths/triplet_sum.py)
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
from __future__ import annotations
2+
3+
from dataclasses import dataclass
4+
5+
6+
# Leetcode Reference : https://leetcode.com/problems/binary-tree-maximum-path-sum/
7+
@dataclass
8+
class TreeNode:
9+
val: int
10+
left: TreeNode | None = None
11+
right: TreeNode | None = None
12+
13+
14+
class GetMaxPathSum:
15+
r"""
16+
17+
GetMaxPathSum takes root node of a tree as initial argument.
18+
Upon calling max_path_sum(), it returns maximum path
19+
sum from the tree.
20+
21+
# Test
22+
23+
The below tree looks like this
24+
10
25+
/ \
26+
5 -3
27+
/ \ \
28+
3 2 11
29+
/ \ \
30+
3 -2 1
31+
32+
Result will be calculated like : 3 -> 3 -> 5 -> 10 -> -3 -> 11
33+
As it is the maximum path possible.
34+
35+
36+
>>> root = TreeNode(10)
37+
>>> root.left = TreeNode(5)
38+
>>> root.right = TreeNode(-3)
39+
>>> root.left.left = TreeNode(3)
40+
>>> root.left.right = TreeNode(2)
41+
>>> root.right.right = TreeNode(11)
42+
>>> root.left.left.left = TreeNode(3)
43+
>>> root.left.left.right = TreeNode(-2)
44+
>>> root.left.right.right = TreeNode(1)
45+
46+
>>> GetMaxPathSum(root).max_path_sum()
47+
29
48+
"""
49+
50+
def __init__(self, root: TreeNode) -> None:
51+
self.sum = -9999999999
52+
self.root = root
53+
54+
def traverse(self, root: TreeNode | None) -> int:
55+
"""
56+
Returns maximum path sum by recursively taking max_path_sum from left
57+
and max_path_sum from right if current Node has a left or right Node.
58+
59+
:param root -> tree root:
60+
:return int:
61+
"""
62+
63+
if root is None:
64+
return 0
65+
66+
right_sum = max(self.traverse(root.right), 0)
67+
left_sum = max(self.traverse(root.left), 0)
68+
69+
val = root.val + right_sum + left_sum
70+
self.sum = max(val, self.sum)
71+
72+
return root.val + max(right_sum, left_sum)
73+
74+
def max_path_sum(self) -> int:
75+
"""
76+
Driver method to get max_path_sum by calling traverse method.
77+
:return max_path_sum:
78+
"""
79+
self.traverse(self.root)
80+
return self.sum
81+
82+
83+
def construct_tree() -> TreeNode:
84+
r"""
85+
The below tree
86+
-10
87+
/ \
88+
9 20
89+
/ \
90+
15 7
91+
92+
>>> root = TreeNode(-10)
93+
>>> root.left = TreeNode(9)
94+
>>> root.right = TreeNode(20)
95+
>>> root.right.left = TreeNode(15)
96+
>>> root.right.right = TreeNode(7)
97+
98+
>>> GetMaxPathSum(construct_tree()).max_path_sum()
99+
42
100+
"""
101+
102+
root = TreeNode(-10)
103+
root.left = TreeNode(9)
104+
root.right = TreeNode(20)
105+
root.right.left = TreeNode(15)
106+
root.right.right = TreeNode(7)
107+
return root
108+
109+
110+
if __name__ == "__main__":
111+
import doctest
112+
113+
doctest.testmod()
114+
115+
tree = GetMaxPathSum(construct_tree())
116+
print(f"{tree.max_path_sum() = }")

0 commit comments

Comments
 (0)