Skip to content

Commit 49ea60b

Browse files
committed
LC 1372. Longest ZigZag Path in a Binary Tree (Python DFS)
1 parent d2bd342 commit 49ea60b

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
394394
| [1343. Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold][lc1343] | 🟠 Medium | [![python](res/py.png)][lc1343py] [![rust](res/rs.png)][lc1343rs] |
395395
| [1345. Jump Game IV][lc1345] | 🔴 Hard | [![python](res/py.png)][lc1345py] [![rust](res/rs.png)][lc1345rs] |
396396
| [1354. Construct Target Array With Multiple Sums][lc1354] | 🔴 Hard | [![python](res/py.png)][lc1354py] |
397+
| [1372. Longest ZigZag Path in a Binary Tree][lc1372] | 🟠 Medium | [![python](res/py.png)][lc1372py] |
397398
| [1383. Maximum Performance of a Team][lc1383] | 🔴 Hard | [![python](res/py.png)][lc1383py] |
398399
| [1402. Reducing Dishes][lc1402] | 🔴 Hard | [![python](res/py.png)][lc1402py] [![rust](res/rs.png)][lc1402rs] |
399400
| [1423. Maximum Points You Can Obtain from Cards][lc1423] | 🟠 Medium | [![python](res/py.png)][lc1423py] |
@@ -1310,6 +1311,8 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
13101311
[lc1345rs]: leetcode/jump-game-iv.rs
13111312
[lc1354]: https://leetcode.com/problems/construct-target-array-with-multiple-sums/
13121313
[lc1354py]: leetcode/construct-target-array-with-multiple-sums.py
1314+
[lc1372]: https://leetcode.com/problems/longest-zigzag-path-in-a-binary-tree/
1315+
[lc1372py]: leetcode/longest-zigzag-path-in-a-binary-tree.py
13131316
[lc1383]: https://leetcode.com/problems/maximum-performance-of-a-team/
13141317
[lc1383py]: leetcode/maximum-performance-of-a-team.py
13151318
[lc1402]: https://leetcode.com/problems/reducing-dishes/
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# 1372. Longest ZigZag Path in a Binary Tree
2+
# 🟠 Medium
3+
#
4+
# https://leetcode.com/problems/longest-zigzag-path-in-a-binary-tree/
5+
#
6+
# Tags: Dynamic Programming - Tree - Depth-First Search - Binary Tree
7+
8+
import timeit
9+
from enum import Enum
10+
from typing import Optional
11+
12+
from utils.binary_tree import BinaryTree, TreeNode
13+
14+
15+
# We could use an enum to make the code easier to read but it makes it
16+
# a little less efficient because it need to create the object.
17+
class Direction(Enum):
18+
RIGHT = "right"
19+
LEFT = "left"
20+
21+
22+
# Use any traversal method to visit all nodes, for each node, record the
23+
# direction that we used to travel there and the length of the zig-zag
24+
# path to it, the path will continue to grow for one of its children and
25+
# will restart for the other one.
26+
#
27+
# Time complexity: O(n) - We visit all nodes and do O(1) work for each.
28+
# Space complexity: O(n) - The stack can grow to size n.
29+
#
30+
# Runtime 367 ms Beats 89.1%
31+
# Memory 26.7 MB Beats 95.60%
32+
class Solution:
33+
def longestZigZag(self, root: Optional[TreeNode]) -> int:
34+
if not root:
35+
return 0
36+
# Traverse the tree, for each node, keep its position in a zig
37+
# zag path and the direction that we traveled to get there.
38+
stack, res = [], 0
39+
if root.left:
40+
stack.append((root.left, Direction.LEFT, 1))
41+
if root.right:
42+
stack.append((root.right, Direction.RIGHT, 1))
43+
while stack:
44+
current, last_dir, path_length = stack.pop()
45+
if path_length > res:
46+
res = path_length
47+
if current.left:
48+
stack.append(
49+
(
50+
current.left,
51+
Direction.LEFT,
52+
path_length + 1 if last_dir == Direction.RIGHT else 1,
53+
)
54+
)
55+
if current.right:
56+
stack.append(
57+
(
58+
current.right,
59+
Direction.RIGHT,
60+
path_length + 1 if last_dir == Direction.LEFT else 1,
61+
)
62+
)
63+
return res
64+
65+
66+
def test():
67+
executors = [Solution]
68+
tests = [
69+
[[1], 0],
70+
[[1, 1, 1, None, 1, None, None, 1, 1, None, 1], 4],
71+
[
72+
[
73+
1,
74+
None,
75+
1,
76+
1,
77+
1,
78+
None,
79+
None,
80+
1,
81+
1,
82+
None,
83+
1,
84+
None,
85+
None,
86+
None,
87+
1,
88+
None,
89+
1,
90+
],
91+
3,
92+
],
93+
]
94+
for executor in executors:
95+
start = timeit.default_timer()
96+
for _ in range(1):
97+
for col, t in enumerate(tests):
98+
sol = executor()
99+
root = BinaryTree.fromList(t[0]).getRoot()
100+
result = sol.longestZigZag(root)
101+
exp = t[1]
102+
assert result == exp, (
103+
f"\033[93m» {result} <> {exp}\033[91m for"
104+
+ f" test {col} using \033[1m{executor.__name__}"
105+
)
106+
stop = timeit.default_timer()
107+
used = str(round(stop - start, 5))
108+
cols = "{0:20}{1:10}{2:10}"
109+
res = cols.format(executor.__name__, used, "seconds")
110+
print(f"\033[92m» {res}\033[0m")
111+
112+
113+
test()

0 commit comments

Comments
 (0)