Skip to content

Commit 9803da5

Browse files
committed
LeetCode 1339. Maximum Product of Splitted Binary Tree
1 parent 8ee0c0f commit 9803da5

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
320320
| [1328. Break a Palindrome][lc1328] | 🟠 Medium | [![python](res/py.png)][lc1328py] |
321321
| [1329. Sort the Matrix Diagonally][lc1329] | 🟠 Medium | [![python](res/py.png)][lc1329py] |
322322
| [1332. Remove Palindromic Subsequences][lc1332] | 🟢 Easy | [![python](res/py.png)][lc1332py] |
323+
| [1339. Maximum Product of Splitted Binary Tree][lc1339] | 🟠 Medium | [![python](res/py.png)][lc1339py] |
323324
| [1354. Construct Target Array With Multiple Sums][lc1354] | 🔴 Hard | [![python](res/py.png)][lc1354py] |
324325
| [1383. Maximum Performance of a Team][lc1383] | 🔴 Hard | [![python](res/py.png)][lc1383py] |
325326
| [1423. Maximum Points You Can Obtain from Cards][lc1423] | 🟠 Medium | [![python](res/py.png)][lc1423py] |
@@ -976,6 +977,8 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
976977
[lc1329py]: leetcode/sort-the-matrix-diagonally.py
977978
[lc1332]: https://leetcode.com/problems/remove-palindromic-subsequences/
978979
[lc1332py]: leetcode/remove-palindromic-subsequences.py
980+
[lc1339]: https://leetcode.com/problems/maximum-product-of-splitted-binary-tree/
981+
[lc1339py]: leetcode/maximum-product-of-splitted-binary-tree.py
979982
[lc1354]: https://leetcode.com/problems/construct-target-array-with-multiple-sums/
980983
[lc1354py]: leetcode/construct-target-array-with-multiple-sums.py
981984
[lc1383]: https://leetcode.com/problems/maximum-performance-of-a-team/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# 1339. Maximum Product of Splitted Binary Tree
2+
# 🟠 Medium
3+
#
4+
# https://leetcode.com/problems/maximum-product-of-splitted-binary-tree/
5+
#
6+
# Tags: Tree - Depth-First Search - Binary Tree
7+
8+
import timeit
9+
from typing import Optional
10+
11+
from utils.binary_tree import BinaryTree
12+
from utils.tree_node import TreeNode
13+
14+
15+
# Do one DFS pass to compute the sum of the entire tree, do a second
16+
# pass to find the maximum product of two sections.
17+
#
18+
# Time complexity: O(n) - We will visit each node twice.
19+
# Space complexity: O(h) - The call stack will grow to the height of the
20+
# tree, best case O(log(n)), worst case O(n).
21+
#
22+
# Runtime 599 ms Beats 68.4%
23+
# Memory 75.6 MB Beats 45.15%
24+
class TwoFunctions:
25+
def maxProduct(self, root: Optional[TreeNode]) -> int:
26+
# One first pass to get the sum of all node's values.
27+
def getTotal(node: Optional[TreeNode]):
28+
if not node:
29+
return 0
30+
return node.val + getTotal(node.left) + getTotal(node.right)
31+
32+
total = getTotal(root)
33+
if not total:
34+
return 0
35+
res = 0
36+
# Second pass to find the maximum product.
37+
def findMaximum(node: Optional[TreeNode]):
38+
if not node:
39+
return 0
40+
subtree_sum = (
41+
node.val + findMaximum(node.left) + findMaximum(node.right)
42+
)
43+
nonlocal res
44+
nonlocal total
45+
res = max(res, (total - subtree_sum) * subtree_sum)
46+
return subtree_sum
47+
48+
findMaximum(root)
49+
return res % (10**9 + 7)
50+
51+
52+
# Simplify the previous solution reusing the same function to compute
53+
# the total and maximum product.
54+
#
55+
# Time complexity: O(n) - We will visit each node twice.
56+
# Space complexity: O(h) - The call stack will grow to the height of the
57+
# tree, best case O(log(n)), worst case O(n).
58+
#
59+
# Runtime 963 ms Beats 24.96%
60+
# Memory 75.6 MB Beats 45.15%
61+
class SingleFunction:
62+
def maxProduct(self, root: Optional[TreeNode]) -> int:
63+
res = total = 0
64+
65+
def dfs(node: Optional[TreeNode]) -> int:
66+
if not node:
67+
return 0
68+
subtree_sum = node.val + dfs(node.left) + dfs(node.right)
69+
if total:
70+
nonlocal res
71+
res = max(res, (total - subtree_sum) * subtree_sum)
72+
return subtree_sum
73+
74+
total = dfs(root)
75+
dfs(root)
76+
return res % (10**9 + 7)
77+
78+
79+
def test():
80+
executors = [
81+
TwoFunctions,
82+
SingleFunction,
83+
]
84+
tests = [
85+
[[], 0],
86+
[[1, 2, 3, 4, 5, 6], 110],
87+
[[1, None, 2, 3, 4, None, None, 5, 6], 90],
88+
]
89+
for executor in executors:
90+
start = timeit.default_timer()
91+
for _ in range(1):
92+
for col, t in enumerate(tests):
93+
sol = executor()
94+
root = BinaryTree.fromList(t[0]).getRoot()
95+
result = sol.maxProduct(root)
96+
exp = t[1]
97+
assert result == exp, (
98+
f"\033[93m» {result} <> {exp}\033[91m for"
99+
+ f" test {col} using \033[1m{executor.__name__}"
100+
)
101+
stop = timeit.default_timer()
102+
used = str(round(stop - start, 5))
103+
cols = "{0:20}{1:10}{2:10}"
104+
res = cols.format(executor.__name__, used, "seconds")
105+
print(f"\033[92m» {res}\033[0m")
106+
107+
108+
test()

0 commit comments

Comments
 (0)