Skip to content

Commit 9846d96

Browse files
committed
feat: add max depth binary tree
1 parent 8c4d078 commit 9846d96

File tree

7 files changed

+306
-1
lines changed

7 files changed

+306
-1
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"problem_name": "maximum_depth_of_binary_tree",
3+
"solution_class_name": "Solution",
4+
"problem_number": "104",
5+
"problem_title": "Maximum Depth of Binary Tree",
6+
"difficulty": "Easy",
7+
"topics": "Tree, Depth-First Search, Breadth-First Search, Binary Tree",
8+
"tags": ["grind-75"],
9+
"readme_description": "Given the `root` of a binary tree, return *its maximum depth*.\n\nA binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node.",
10+
"readme_examples": [
11+
{
12+
"content": "![Example 1](https://assets.leetcode.com/uploads/2020/11/26/tmp-tree.jpg)\n\n```\nInput: root = [3,9,20,null,null,15,7]\nOutput: 3\n```"
13+
},
14+
{ "content": "```\nInput: root = [1,null,2]\nOutput: 2\n```" }
15+
],
16+
"readme_constraints": "- The number of nodes in the tree is in the range `[0, 10^4]`.\n- `-100 <= Node.val <= 100`",
17+
"readme_additional": "",
18+
"solution_imports": "from leetcode_py import TreeNode",
19+
"solution_methods": [
20+
{
21+
"name": "max_depth",
22+
"parameters": "root: TreeNode[int] | None",
23+
"return_type": "int",
24+
"dummy_return": "0"
25+
}
26+
],
27+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom leetcode_py import TreeNode\nfrom .solution import Solution",
28+
"test_class_name": "MaximumDepthOfBinaryTree",
29+
"test_helper_methods": [
30+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
31+
],
32+
"test_methods": [
33+
{
34+
"name": "test_max_depth",
35+
"parametrize": "root_list, expected",
36+
"parametrize_typed": "root_list: list[int | None], expected: int",
37+
"test_cases": "[([3, 9, 20, None, None, 15, 7], 3), ([1, None, 2], 2), ([], 0)]",
38+
"body": "root = TreeNode.from_list(root_list)\nresult = self.solution.max_depth(root)\nassert result == expected"
39+
}
40+
],
41+
"playground_imports": "from solution import Solution\nfrom leetcode_py import TreeNode",
42+
"playground_test_case": "# Example test case\nroot_list = [3, 9, 20, None, None, 15, 7]\nexpected = 3",
43+
"playground_execution": "root = TreeNode.from_list(root_list)\nresult = Solution().max_depth(root)\nresult",
44+
"playground_assertion": "assert result == expected"
45+
}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PYTHON_VERSION = 3.13
2-
PROBLEM ?= string_to_integer_atoi
2+
PROBLEM ?= maximum_depth_of_binary_tree
33
FORCE ?= 0
44
COMMA := ,
55

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Maximum Depth of Binary Tree
2+
3+
**Difficulty:** Easy
4+
**Topics:** Tree, Depth-First Search, Breadth-First Search, Binary Tree
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 104](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/)
8+
9+
## Problem Description
10+
11+
Given the `root` of a binary tree, return _its maximum depth_.
12+
13+
A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node.
14+
15+
## Examples
16+
17+
### Example 1:
18+
19+
![Example 1](https://assets.leetcode.com/uploads/2020/11/26/tmp-tree.jpg)
20+
21+
```
22+
Input: root = [3,9,20,null,null,15,7]
23+
Output: 3
24+
```
25+
26+
### Example 2:
27+
28+
```
29+
Input: root = [1,null,2]
30+
Output: 2
31+
```
32+
33+
## Constraints
34+
35+
- The number of nodes in the tree is in the range `[0, 10^4]`.
36+
- `-100 <= Node.val <= 100`

leetcode/maximum_depth_of_binary_tree/__init__.py

Whitespace-only changes.
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "imports",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from solution import Solution\n",
11+
"\n",
12+
"from leetcode_py import TreeNode"
13+
]
14+
},
15+
{
16+
"cell_type": "code",
17+
"execution_count": 2,
18+
"id": "setup",
19+
"metadata": {},
20+
"outputs": [],
21+
"source": [
22+
"# Example test case\n",
23+
"root_list = [3, 9, 20, None, None, 15, 7]\n",
24+
"expected = 3"
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": 3,
30+
"id": "execute",
31+
"metadata": {},
32+
"outputs": [
33+
{
34+
"data": {
35+
"text/plain": [
36+
"3"
37+
]
38+
},
39+
"execution_count": 3,
40+
"metadata": {},
41+
"output_type": "execute_result"
42+
}
43+
],
44+
"source": [
45+
"root = TreeNode.from_list(root_list)\n",
46+
"result = Solution().max_depth(root)\n",
47+
"result"
48+
]
49+
},
50+
{
51+
"cell_type": "code",
52+
"execution_count": 5,
53+
"id": "3d476584",
54+
"metadata": {},
55+
"outputs": [
56+
{
57+
"data": {
58+
"text/html": [
59+
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
60+
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
61+
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
62+
"<!-- Generated by graphviz version 13.1.2 (20250808.2320)\n",
63+
" -->\n",
64+
"<!-- Pages: 1 -->\n",
65+
"<svg width=\"170pt\" height=\"188pt\"\n",
66+
" viewBox=\"0.00 0.00 170.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
67+
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
68+
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 166,-184 166,4 -4,4\"/>\n",
69+
"<!-- 0 -->\n",
70+
"<g id=\"node1\" class=\"node\">\n",
71+
"<title>0</title>\n",
72+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
73+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"63\" y=\"-156.95\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
74+
"</g>\n",
75+
"<!-- 1 -->\n",
76+
"<g id=\"node2\" class=\"node\">\n",
77+
"<title>1</title>\n",
78+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
79+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"27\" y=\"-84.95\" font-family=\"Times,serif\" font-size=\"14.00\">9</text>\n",
80+
"</g>\n",
81+
"<!-- 0&#45;&gt;1 -->\n",
82+
"<g id=\"edge1\" class=\"edge\">\n",
83+
"<title>0&#45;&gt;1</title>\n",
84+
"<path fill=\"none\" stroke=\"black\" d=\"M54.65,-144.76C50.42,-136.55 45.19,-126.37 40.42,-117.09\"/>\n",
85+
"<polygon fill=\"black\" stroke=\"black\" points=\"43.68,-115.79 36,-108.49 37.46,-118.99 43.68,-115.79\"/>\n",
86+
"</g>\n",
87+
"<!-- 2 -->\n",
88+
"<g id=\"node3\" class=\"node\">\n",
89+
"<title>2</title>\n",
90+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
91+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"99\" y=\"-84.95\" font-family=\"Times,serif\" font-size=\"14.00\">20</text>\n",
92+
"</g>\n",
93+
"<!-- 0&#45;&gt;2 -->\n",
94+
"<g id=\"edge2\" class=\"edge\">\n",
95+
"<title>0&#45;&gt;2</title>\n",
96+
"<path fill=\"none\" stroke=\"black\" d=\"M71.35,-144.76C75.58,-136.55 80.81,-126.37 85.58,-117.09\"/>\n",
97+
"<polygon fill=\"black\" stroke=\"black\" points=\"88.54,-118.99 90,-108.49 82.32,-115.79 88.54,-118.99\"/>\n",
98+
"</g>\n",
99+
"<!-- 3 -->\n",
100+
"<g id=\"node4\" class=\"node\">\n",
101+
"<title>3</title>\n",
102+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
103+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"63\" y=\"-12.95\" font-family=\"Times,serif\" font-size=\"14.00\">15</text>\n",
104+
"</g>\n",
105+
"<!-- 2&#45;&gt;3 -->\n",
106+
"<g id=\"edge3\" class=\"edge\">\n",
107+
"<title>2&#45;&gt;3</title>\n",
108+
"<path fill=\"none\" stroke=\"black\" d=\"M90.65,-72.76C86.42,-64.55 81.19,-54.37 76.42,-45.09\"/>\n",
109+
"<polygon fill=\"black\" stroke=\"black\" points=\"79.68,-43.79 72,-36.49 73.46,-46.99 79.68,-43.79\"/>\n",
110+
"</g>\n",
111+
"<!-- 4 -->\n",
112+
"<g id=\"node5\" class=\"node\">\n",
113+
"<title>4</title>\n",
114+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"135\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
115+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"135\" y=\"-12.95\" font-family=\"Times,serif\" font-size=\"14.00\">7</text>\n",
116+
"</g>\n",
117+
"<!-- 2&#45;&gt;4 -->\n",
118+
"<g id=\"edge4\" class=\"edge\">\n",
119+
"<title>2&#45;&gt;4</title>\n",
120+
"<path fill=\"none\" stroke=\"black\" d=\"M107.35,-72.76C111.58,-64.55 116.81,-54.37 121.58,-45.09\"/>\n",
121+
"<polygon fill=\"black\" stroke=\"black\" points=\"124.54,-46.99 126,-36.49 118.32,-43.79 124.54,-46.99\"/>\n",
122+
"</g>\n",
123+
"</g>\n",
124+
"</svg>\n"
125+
],
126+
"text/plain": [
127+
"TreeNode([3, 9, 20, None, None, 15, 7])"
128+
]
129+
},
130+
"execution_count": 5,
131+
"metadata": {},
132+
"output_type": "execute_result"
133+
}
134+
],
135+
"source": [
136+
"root"
137+
]
138+
},
139+
{
140+
"cell_type": "code",
141+
"execution_count": 4,
142+
"id": "test",
143+
"metadata": {},
144+
"outputs": [],
145+
"source": [
146+
"assert result == expected"
147+
]
148+
}
149+
],
150+
"metadata": {
151+
"kernelspec": {
152+
"display_name": "leetcode-py-py3.13",
153+
"language": "python",
154+
"name": "python3"
155+
},
156+
"language_info": {
157+
"codemirror_mode": {
158+
"name": "ipython",
159+
"version": 3
160+
},
161+
"file_extension": ".py",
162+
"mimetype": "text/x-python",
163+
"name": "python",
164+
"nbconvert_exporter": "python",
165+
"pygments_lexer": "ipython3",
166+
"version": "3.13.7"
167+
}
168+
},
169+
"nbformat": 4,
170+
"nbformat_minor": 5
171+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from leetcode_py import TreeNode
2+
3+
4+
class Solution:
5+
# Time: O(n)
6+
# Space: O(h)
7+
def max_depth(self, root: TreeNode | None) -> int:
8+
if not root:
9+
return 0
10+
11+
left_depth = self.max_depth(root.left)
12+
right_depth = self.max_depth(root.right)
13+
14+
return 1 + max(left_depth, right_depth)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import pytest
2+
3+
from leetcode_py import TreeNode
4+
from leetcode_py.test_utils import logged_test
5+
6+
from .solution import Solution
7+
8+
9+
class TestMaximumDepthOfBinaryTree:
10+
def setup_method(self):
11+
self.solution = Solution()
12+
13+
@pytest.mark.parametrize(
14+
"root_list, expected",
15+
[
16+
# Original examples
17+
([3, 9, 20, None, None, 15, 7], 3),
18+
([1, None, 2], 2),
19+
([], 0),
20+
# Single node
21+
([1], 1),
22+
# Left skewed tree (depth 3)
23+
([1, 2, None, 3], 3),
24+
# Right skewed tree (depth 2)
25+
([1, None, 2], 2),
26+
# Balanced tree
27+
([1, 2, 3, 4, 5, 6, 7], 3),
28+
# Unbalanced tree (left heavy)
29+
([1, 2, 3, 4, 5, None, None, 6, 7], 4),
30+
# Two nodes
31+
([1, 2], 2),
32+
([1, None, 2], 2),
33+
],
34+
)
35+
@logged_test
36+
def test_max_depth(self, root_list: list[int | None], expected: int):
37+
root = TreeNode.from_list(root_list)
38+
result = self.solution.max_depth(root)
39+
assert result == expected

0 commit comments

Comments
 (0)